Android字体ttf或otf字体呈现随机symblols /字母

时间:2014-06-02 20:57:49

标签: android fonts android-custom-view text-rendering android-typeface

我有一个自定义View我正在绘制一些文字。我正在使用资产文件夹

中提供的各种免费otf / ttf字体文件
public class ProjectView extends View {
    private final Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private void init(Context context) {
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setAntiAlias(true);

        typeface = Typeface.createFromAsset(context.getAssets(), "fonts" + File.separator + fontFileName);
        textPaint.setTypeface(typeface);
    }
}

除了一件事之外,一切似乎都工作正常:我正在绘制的单词随机乱搞,意味着这些字母随机替换为其他字母或符号。

以下是一个例子:

enter image description here

正确的单词位于左侧图像中,但有时会像右图中一样绘制。再次调用invalidate()所有内容再次正确呈现可以解决问题。

这个效果在ListView中更明显,因为频繁重绘,因为我在每个项目点击时调用notifyDatasetChanged()。在适配器中我使用它:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = convertView;
        ViewHolder holder;
        if (convertView == null) {
            view = inflater.inflate(R.layout.list_item_fonts, null);

            holder = new ViewHolder();
            holder.txtFont = (TextView) view.findViewById(R.id.txtFont);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        //tried this two but no success
        holder.txtFont.setPaintFlags(holder.txtFont.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.DEV_KERN_TEXT_FLAG);
        holder.txtFont.getPaint().setSubpixelText(true);

        holder.txtFont.setTextSize(TypedValue.COMPLEX_UNIT_SP, fonts.get(position).getSize());

        holder.txtFont.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts" + File.separator + font.getFileName()));
}

说实话,我不知道是什么导致这种情况或如何阻止它。任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:3)

每次调用getView时都会创建字体。这是低效的,并且可能在加载和解析字体文件时引起竞争。

在活动中包含所有已加载字体的地图,并仅加载每个字体一次。

如果许多活动和视图使用相同的字体,我甚至会尝试管理Application类上的字体。

答案 1 :(得分:0)

这可能会对某人有所帮助。我遇到了同样的问题。我使用lru缓存解决了它。

import android.content.Context;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.MetricAffectingSpan;
import android.util.LruCache;

public class TypefaceSpan extends MetricAffectingSpan {
    private static LruCache<String, Typeface> sTypefaceCache = new LruCache<>(12);
    private Typeface mTypeface;

    public TypefaceSpan(Context context, String typefaceName) {
        mTypeface = sTypefaceCache.get(typefaceName);

        if (mTypeface == null) {
            mTypeface = Typeface.createFromAsset(context.getApplicationContext().getAssets(),
                    String.format("fonts/%s", typefaceName));
            sTypefaceCache.put(typefaceName, mTypeface);
        }
    }

    @Override
    public void updateMeasureState(TextPaint p) {
        p.setTypeface(mTypeface);
        p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
    }

    @Override
    public void updateDrawState(TextPaint tp) {
        tp.setTypeface(mTypeface);
        tp.setFlags(tp.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
    }
}

示例:

private TypefaceSpan typefaceSpan;

构造

typefaceSpan = new TypefaceSpan(context, "name_of_font.otf");

getView:

typefaceSpan.updateDrawState(holder.title.getPaint());