仅通过XML创建自定义TrueType字体

4
有没有什么办法可以在不提供任何Java代码的情况下,只使用XML为TextView(或其子类)传递自定义字体?
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/CustomFont.ttf");

如果您想使用自定义字体,则必须编写Java代码。 - anddev
1个回答

5

纯粹通过XML无法实现,但是您可以创建自定义视图并从XML中引用该视图。这样,您只需要编写一次代码,就可以在多个布局中重复使用它。

例如,声明 FontTextView 类:

package com.example;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontTextView extends TextView {

    /** 
     *  Note that when generating the class from code, you will need
     *  to call setCustomFont() manually.
     */
    public FontTextView(Context context) {
        super(context);
    }

    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(this, attrs);
    }

    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(this, attrs);
    }

    private void setCustomFont(Context context, AttributeSet attrs) {
        if (isInEditMode()) {
            // Ignore if within Eclipse
            return;
        }
        String font = "myDefaultFont.ttf";
        if (attrs != null) {
            // Look up any layout-defined attributes
            TypedArray a = obtainStyledAttributes(attrs,
                    R.styleable.FontTextView);
            for (int i = 0; i < a.getIndexCount(); i++) {
                int attr = a.getIndex(i);
                switch (attr) {
                case R.styleable.FontTextView_customFont:
                    font = a.getString(attr, 0);
                    break;
                }
            }
            a.recycle();
        }
        Typeface tf = null;
        try {
            tf = Typeface.createFromAsset(getAssets(), font);
        } catch (Exception e) {
            Log.e("Could not get typeface: " + e.getMessage());
        }
        setTypeface(tf);
    }

}

res/values/attrs.xml中定义属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="FontTextView">
        <attr name="customFont" format="string" />
    </declare-styleable>

</resources>

在布局中使用它:

  1. Declare the namespace:

    xmlns:custom="http://schemas.android.com/apk/res/com.example"
    
  2. Use the FontTextView:

    <com.example.FontTextView
        android:id="@+id/introduction"
        customFont="myCustomFont.ttf"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello world!" />
    

对不起,但如果我想要使用 Button 或 CheckedTextView 或 CompoundButton 或其他类型的组件,我需要为它们每个创建一个扩展吗?这并不是一个好的解决方案,很抱歉 :-( - s_id
2
setCustomFont() 泛化为静态上下文,如果您始终使用 XML 构造函数,则每个视图元素只需要定义一个构造函数。实际上,我发现只有五个或更少的不同控件需要扩展,而且由于您不需要在视图或布局周围编写任何额外的代码,因此我发现这是最佳解决方案。 - Paul Lammertsma
@s_id 这是最好的解决方案,除了添加一些静态缓存以便您不必每次创建新的 FontTextView 对象时都加载 Typeface。 - Tyler
@Styler 注意静态字段,可能会无意中使整个活动保留在内存中。我建议扩展Application类并通过它获取Typeface。 - Paul Lammertsma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接