如何在 android 中设置 Styles.xml 的字体

How to set the font from Styles.xml in android

我有什么

  1. 我有一个自定义 class 继承 AppCompatTextView
  2. 我在 attires.xml 中定义了自定义属性 textformat 并且 我正在传递我需要从 xml
  3. 设置的字体

样式文件

<style name="HeaderFilterName">
        <item name="android:src">@drawable/back_button</item>
        <item name="android:text">@string/str_filter_edit</item>
        <item name="android:gravity">center</item>
        <item name="android:textSize">@dimen/Header_Filter_Name_Text_size</item>
        <item name="android:layout_weight">1</item>
    </style>

XML

    <customViews.CustomTftTextView
    android:id="@+id/txtScreenNameId"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:textformat="fonts/sf_san_fransisco.ttf"
    style="@style/HeaderFilterName"/>

attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="customfont">
        <attr name="textformat" format="string"/>
    </declare-styleable>
</resources>

CustomTftTextView.java

public class CustomTftTextView extends AppCompatTextView {
    private String text;

    public CustomTftTextView(final Context context) {
        this(context, null);
        Initialize(text,context);
    }

    public CustomTftTextView(final Context context, final AttributeSet attrs) {
        this(context, attrs, 0);
        text = context.getResources().obtainAttributes(attrs, R.styleable.customfont).getString(R.styleable.customfont_textformat);
        Initialize(text,context);
    }

    public CustomTftTextView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
        text = context.getResources().obtainAttributes(attrs, R.styleable.customfont).getString(R.styleable.customfont_textformat);
        Initialize(text,context);
    }

    private void Initialize(String format, Context context) {

        Typeface mTypeface;
        if (format != null)
        {
            mTypeface = Typeface.createFromAsset(context.getAssets(), format);
        }
        else
        {
            mTypeface = Typeface.createFromAsset(context.getAssets(), "fonts/sf_san_fransisco.ttf");
        }
        setTypeface(mTypeface, Typeface.NORMAL);
        setLineSpacing(0.0f, 1.4f);
    }
}

虽然上面的代码工作完美,但如果我在 style 文件中移动 app:textformat,字体不会设置。

<style name="HeaderFilterName">
            <item name="android:src">@drawable/back_button</item>
            <item name="android:text">@string/str_filter_edit</item>
            <item name="textformat">@string/custom_font_medium </item>
<item name="android:gravity">center</item>
            <item name="android:textSize">@dimen/Header_Filter_Name_Text_size</item>
            <item name="android:layout_weight">1</item>
        </style>

strings.xml

<string name="custom_font_medium">fonts/sf_san_fransisco.ttf</string>

如何正确实现这一点

确保在 styles.xml 中使用了如下命名空间

<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app='http://schemas.android.com/apk/res-auto'>

如果您查看 Resources#obtainAttributes() method 的文档,它说:

Retrieve a set of basic attribute values from an AttributeSet, not performing styling of them using a theme and/or style resources.

要获取应用了您的样式的属性,请改用 Context#obtainStyledAttributes() 方法。还建议保留对该 return 的引用,这样您可以在完成后 recycle() 它。例如:

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.customfont);
text = a.getString(R.styleable.customfont_textformat);
a.recycle();