为 TextView 设置自定义字体导致 onCreate 需要更长的时间来构建

Setting Custom Font for TextView causing the onCreate to take longer to build

我目前正在我的项目中实现 Roboto 字体。对于某些片段,有很多 TextView 的。我正在创建一个扩展 TextView 以实现自定义字体的自定义视图。有没有更好的方法来加载字体而不增加 onCreate 时间?

扩展 TextView

public class TextViewFont extends TextView {

    public TextViewFont(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    public TextViewFont(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);

    }

    public TextViewFont(Context context) {
        super(context);
        init(null);
    }

    private void init(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TextViewFont);
            String fontName = a.getString(R.styleable.TextViewFont_fontName);
            if (fontName != null) {
                Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + fontName);
                setTypeface(myTypeface);
            }
            a.recycle();
        }
    }
}

XML

<com.eugene.fithealthmaingit.Custom.TextViewFont
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_weight="1"
            android:text="@string/dinner"
            android:textColor="@color/text_color"
            android:textSize="16sp"
            app:fontName="Roboto-Regular.ttf"/>

多少TextView的例子

这是救了我一命的图书馆 Calligraphy。真的很好用也很方便。

Typeface.createfromassets 是一个耗时的过程。您应该在 class 中将字体声明为静态变量,然后在构造函数中使用它。

但是在这里您要在每个文本视图的构造函数中加载字体。

如果您有多种字体,请将所有字体设置为静态并适当使用。

更新代码:

public class TextViewFont extends TextView {

        public static Typeface typeface1 = Typeface.createFromAsset(getContext().getAssets(), "fonts/fontName1");
        public static Typeface typeface2 = Typeface.createFromAsset(getContext().getAssets(), "fonts/fontName2");
        public static Typeface typeface3 = Typeface.createFromAsset(getContext().getAssets(), "fonts/fontName3");
        public static Typeface typeface4 = Typeface.createFromAsset(getContext().getAssets(), "fonts/fontName4");
        public static Typeface typeface5 = Typeface.createFromAsset(getContext().getAssets(), "fonts/fontName5");

        public TextViewFont(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(attrs);
        }

        public TextViewFont(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs);

        }

        public TextViewFont(Context context) {
            super(context);
            init(null);
        }

        private void init(AttributeSet attrs) {
            if (attrs != null) {
                TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TextViewFont);
                String fontName = a.getString(R.styleable.TextViewFont_fontName);
                if (fontName != null) {
                    setTypeface(getTypeFace(fontName));
                }
                a.recycle();
            }
        }


        public Typeface getTypeFace(String fontName){
            if(fontName.equals("fontName1")){
                return typeface1;
            }else if(fontName.equals("fontName2")){
                return typeface2;
            }else if(fontName.equals("fontName3")){
                return typeface3;
            }else if(fontName.equals("fontName4")){
                return typeface4;
            }else if(fontName.equals("fontName5")){
                return typeface5;
            }
        }
    } 
}

尝试使用实例单例或应用程序单例。看看这是否有效。所以你可以调用 TextLover.get(context).getFont(id)。它将即时创建并缓存它。这样您的其他视图也可以重用字体缓存。例如。按钮

class TextLover {

    private static TextLover singleton;

    private final Context context;

    private final SparseArray<Typeface> faces = new SparseArray<Typeface>();

    public TextLover get(Context context) {
        if (singleton == null) {
            singleton = new TextLover(context);
        }
        return singleton;
    }

    private TextLover(Context context) {
        this.context = context;
    }

    private static final String[] fonts = {
        "fonts/fontName1",
        "fonts/fontName2",
        "fonts/fontName3",
        "fonts/fontName4",
        "fonts/fontName5",
            ...
        "fonts/fontName100"
    }

    // NOTE you need a mapping of ids to each asset font in fonts[]

    public Typeface getFont(int id) {
        Typeface font = faces.get(id);
        if (font == null) {
            font = Typeface.createFromAsset(context.getAssets(), fonts[id]);
            faces.append(id, font);
        }
        return font;
    }

}