【问题标题】:Performance issue on custom font TextView自定义字体 TextView 的性能问题
【发布时间】:2013-03-11 11:58:30
【问题描述】:

我有一个自定义的 TextView,带有个性化的字体属性:

public class TextViewPlus extends TextView {
    private static final String TAG = "TextViewPlus";
    public TextViewPlus(Context context) {
        super(context);
    }
    public TextViewPlus(Context context, AttributeSet attrs) {
        // This is called all the time I scroll my ListView
        // and it make it very slow. 
        super(context, attrs);
        setCustomFont(context, attrs);
    }
    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }
    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }
    public boolean setCustomFont(Context ctx, String asset) {
        Typeface tf = null;
        try {
            tf = Typeface.createFromAsset(ctx.getAssets(), asset);  
            setTypeface(tf); 
        } catch (Exception e) {
            Log.e(TAG, "Could not get typeface: "+e.getMessage());
            return false;
        }
        return true;
    }
}

我在具有 customFont="ArialRounded.ttf" 属性的 XML 文件中使用它,它运行良好。

我在 ListView 中使用这个 TextViewPlus,填充了 ArrayAdapter。

TextViewPlus dataText = (TextViewPlus) itemView.findViewById(R.id.data_text);
dataText.setText("My data String");

我的问题是,当我滚动 ListView 时,性能很糟糕!非常缓慢且充满滞后。 TextViewPlus 构造函数 n°2 在我滚动列表时一直被调用。

如果我在普通的 TextView 中更改 TextViewPlus,并使用 dataText.setTypeface(myFont),一切都会顺利并且运行良好。

如何在没有性能问题的情况下使用 TextViewPlus?

【问题讨论】:

  • 您是否尝试过在某处缓存您的 Typeface,所以它不会每次都被创建?
  • 我现在做。我尝试了 Praful Bhatnagar 的解决方案,效果很好

标签: android performance textview


【解决方案1】:

为什么不将创建的typface 对象保存在内存中,这样就不会在每次创建文本视图时都创建。

以下是创建和缓存字体对象的示例类:

public class TypeFaceProvider {

    public static final String TYPEFACE_FOLDER = "fonts";
    public static final String TYPEFACE_EXTENSION = ".ttf";

    private static Hashtable<String, Typeface> sTypeFaces = new Hashtable<String, Typeface>(
        4);

    public static Typeface getTypeFace(Context context, String fileName) {
    Typeface tempTypeface = sTypeFaces.get(fileName);

    if (tempTypeface == null) {
        String fontPath = new StringBuilder(TYPEFACE_FOLDER).append('/').append(fileName).append(TYPEFACE_EXTENSION).toString();
        tempTypeface = Typeface.createFromAsset(context.getAssets(), fontPath);
        sTypeFaces.put(fileName, tempTypeface);
    }

    return tempTypeface;
    }
}

【讨论】:

  • 我很高兴它起作用了,但是如果您正确实现了 ListView 适配器,缓存不会给您带来任何性能提升。也就是说,视图(包括文本视图)被重用。如果它们被正确地重用,那么在滚动过程中不应再加载任何 .ttf 文件。
  • @Zsolt Safrany 抱歉,但这不太对。如果不影响滚动,它将影响页面加载时间。假设您有 7 个可见项目,每个项目 3 个文本视图,那么字体将从资产中加载 21 次,这很糟糕。
  • @HamzehSoboh 这是一个很好的观点——我还没有考虑过。
  • 这个类怎么用?
  • @PrafulBhatnagar 非常感谢,兄弟。我在RecyclerViewViewpager 中使用了自定义字体。 RecyclerView 的一项有 2 种字体,ViewPager 选项卡标题有两种字体(一种用于选中,另一种用于禁用),我在想为什么我的应用程序在滚动和滑动时很慢,今天我意识到了这一点并开始寻找解决方案并在这里结束。
猜你喜欢
  • 2013-02-26
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-08
  • 2014-05-19
  • 2012-06-09
  • 2012-04-02
相关资源
最近更新 更多