如何在 Android 主题中正确设置两种不同的字体

How to properly set two different fonts in Android Theme

我有一个 android 应用程序,可以选择英语和阿拉伯语。 我的问题是我需要为每种语言使用特定的字体。

实现这个的正确方法是什么?

我的想法是在 styles.xml 中创建两个不同的主题,如下所示:

<resources>

    <!-- English application theme. -->
    <style name="EnglishTheme" parent="Theme.AppCompat.Light.NoActionBar">
        ... all my others attributes ...

        <item name="pathBoldFont">fonts/FontEnglish-Bold.ttf</item>
        <item name="pathRegularFont">fonts/FontEnglish-Regular.ttf</item>
        <item name="pathThinFont">fonts/FontEnglish-Thin.ttf</item>
    </style>

    <!-- Arabic application theme. -->
    <style name="ArabicTheme" parent="Theme.AppCompat.Light.NoActionBar">
        ... all my others attributes ...

        <item name="pathBoldFont">fonts/FontArabic-Bold.ttf</item>
        <item name="pathRegularFont">fonts/FontArabic-Regular.ttf</item>
        <item name="pathThinFont">fonts/FontArabic-Thin.ttf</item>
    </style>

</resources>

在应用程序运行时,我检查用户的语言环境并加载正确的主题。但显然,这不是很DRY,因为我必须每隔一个主题的属性写两次。

我了解到无法以编程方式更新主题属性(在我的情况下只是字体),所以有什么更好的解决方案?

仅供参考,我使用 InflationX/Calligraphy 作为我的自定义字体。

只需创建一个自定义 TextView Class,您可以在其中设置字体,并在其中每当您获得字体时检查所选语言

public class CustomTextView extends android.support.v7.widget.AppCompatTextView {
    public CustomTextView (Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CustomTextView,
                0, 0);

        try {
            int custom_font = a.getInt(R.styleable.CustomTextView_custom_font, 0);

            switch (custom_font) {
            //Regular    
            case 0:
                    if(language == "english")
                    setTypeface(/*return Typeface Regular for english*/);
                    else setTypeface(/*return Typeface Regular  for arabic*/);
                    break;
                //Bold
                case 1:
                    if(language == "english")
                    setTypeface(/*return Typeface Boldfor english*/);
                    else setTypeface(/*return Typeface Boldfor arabic*/);
                    break;

            }

        } finally {
            a.recycle();
        }
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

}

在你的 attr.xml

<declare-styleable name="CustomTextView">
    <attr name="custom_font" format="string">
        <enum name="regular" value="0" />
        <enum name="bold" value="1" />
    </attr>
</declare-styleable>

这样使用

        <CustomTextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         app:custom_font="bold"/>