java - 在使用xml的android TextView中使用自定义字体

标签 java android xml android-layout fonts

我已将自定义字体文件添加到我的 Assets /字体文件夹中。如何从我的 XML 中使用它?

我可以从如下代码中使用它:

TextView text = (TextView) findViewById(R.id.textview03);
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Molot.otf");
text.setTypeface(tf);

我不能使用 android:typeface="/fonts/Molot.otf" 属性从 XML 中执行此操作吗?

最佳答案

简短回答:不。Android 没有内置支持通过 XML 将自定义字体应用于文本小部件。

但是,有一种解决方法并不难实现。

第一

您需要定义自己的样式。在您的/res/values 文件夹中,打开/创建 attrs.xml 文件并添加一个可声明样式的对象,如下所示:

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

第二

假设您想经常使用这个小部件,您应该为加载的 Typeface 对象设置一个简单的缓存,因为从内存中动态加载它们可能需要一些时间。比如:

public class FontManager {
    private static FontManager instance;

    private AssetManager mgr;

    private Map<String, Typeface> fonts;

    private FontManager(AssetManager _mgr) {
        mgr = _mgr;
        fonts = new HashMap<String, Typeface>();
    }

    public static void init(AssetManager mgr) {
        instance = new FontManager(mgr);
    }

    public static FontManager getInstance() {
        if (instance == null) {
            // App.getContext() is just one way to get a Context here
            // getContext() is just a method in an Application subclass
            // that returns the application context
            AssetManager assetManager = App.getContext().getAssets();
            init(assetManager);
        }
        return instance;
    }

    public Typeface getFont(String asset) {
        if (fonts.containsKey(asset))
            return fonts.get(asset);

        Typeface font = null;

        try {
            font = Typeface.createFromAsset(mgr, asset);
            fonts.put(asset, font);
        } catch (Exception e) {

        }

        if (font == null) {
            try {
                String fixedAsset = fixAssetFilename(asset);
                font = Typeface.createFromAsset(mgr, fixedAsset);
                fonts.put(asset, font);
                fonts.put(fixedAsset, font);
            } catch (Exception e) {

            }
        }

        return font;
    }

    private String fixAssetFilename(String asset) {
        // Empty font filename?
        // Just return it. We can't help.
        if (TextUtils.isEmpty(asset))
            return asset;

        // Make sure that the font ends in '.ttf' or '.ttc'
        if ((!asset.endsWith(".ttf")) && (!asset.endsWith(".ttc")))
            asset = String.format("%s.ttf", asset);

        return asset;
    }
}

这个允许您使用 .ttc 文件扩展名,但它未经测试。

第三

创建一个子类 TextView 的新类。这个特定示例考虑了定义的 XML 字体(bolditalic 等)并将其应用于字体(假设您使用的是 .ttc 文件)。

/**
 * TextView subclass which allows the user to define a truetype font file to use as the view's typeface.
 */
public class FontText extends TextView {
    public FontText(Context context) {
        this(context, null);
    }

    public FontText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FontText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        if (isInEditMode())
            return;

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FontText);

        if (ta != null) {
            String fontAsset = ta.getString(R.styleable.FontText_typefaceAsset);

            if (!TextUtils.isEmpty(fontAsset)) {
                Typeface tf = FontManager.getInstance().getFont(fontAsset);
                int style = Typeface.NORMAL;
                float size = getTextSize();

                if (getTypeface() != null)
                    style = getTypeface().getStyle();

                if (tf != null)
                    setTypeface(tf, style);
                else
                    Log.d("FontText", String.format("Could not create a font from asset: %s", fontAsset));
            }
        }
    }
}

终于

用完全限定的类名替换 XML 中的 TextView 实例。像声明 Android 命名空间一样声明您的自定义命名空间。请注意,“typefaceAsset”应指向/assets 目录中包含的 .ttf 或 .ttc 文件。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.FontText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is a custom font text"
        custom:typefaceAsset="fonts/AvenirNext-Regular.ttf"/>
</RelativeLayout>

关于java - 在使用xml的android TextView中使用自定义字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9327053/

相关文章:

java - 验证表达式

java - 在 Url 查询参数中区分空值和空字符串 ("")

android - Activity 问题中的 findViewById

android - 从不工作的android项目中删除所有未使用的资源

c++ - 是否可以使用 POCO XPath 获取元素文本

java - hbm2ddl.auto 设置为更新时 hibernate 错误

android,响应布局调整大小

iphone - 如何从字典中检索数组,然后在该数组中检索字典?

java - Jersey REST 日期 @XmlAttribute 导致非法参数异常

java - 将文件从源复制到计算机