Android自定义字体问题

时间:2015-08-10 17:17:07

标签: android fonts

我正在开发一个Android应用程序。在这个应用程序中,我使用自定义字体(avenir_bold_font)。我正在使用以下方法将字体设置为按钮。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] input = new string[] {
                "A.B.C.1.2.3.4.zip",
                "A.B.C.1.2.3.5.zip",
                "A.B.C.3.4.5.dll",
                "A.B.C.1.2.3.6.zip",
                "A.B.C.1.2.3.dll",
                "X.Y.Z.7.8.9.0.zip",
                "X.Y.Z.7.8.9.1.zip"
            };

            var parsed = input.Select(x => x.Split(new char[] { '.' }))
                .Select(y => new
                {
                    name = string.Join(".", new string[] { y[0], y[1], y[2] }),
                    ext = y[y.Count() - 1],
                    major = int.Parse(y[3]),
                    minor = int.Parse(y[4]),
                    build = int.Parse(y[5]),
                    revision = y.Count() == 7 ? (int?)null : int.Parse(y[6])
                }).ToList();

            var results = parsed.Where(x => (x.major >= 1) && (x.major <= 3)).ToList();

            var dict = parsed.GroupBy(x => x.name, y => y)
                .ToDictionary(x => x.Key, y => y.ToList());

            var abc = dict["A.B.C"];
        }
    }
}
​
​

使用上述方法可以毫无困难地将字体设置为按钮。但是在上面的方法中,我每次调用它时都会创建Typeface对象。

所以我已经在上面的方法中进行了更改,我已经将Typeface局部变量转换为静态变量,这样它将提高性能,但是当我创建Typeface对象为静态时,它不起作用。它无法设置字体

1 个答案:

答案 0 :(得分:3)

我建议创建一个实用程序类来缓存加载的字体 - 如下所示:

public class TypefaceCache {
    private final static Map<String, Typeface> cache = new HashMap<String, Typeface>();

    private TypefaceCache() { /* do not allow instance creation */ }

    public static Typeface getTypeface(Context context, String path){
        Typeface tf = cache.get(path);
        if (tf == null) {
            tf = Typeface.createFromAsset(context.getAssets(), path);
            cache.put(path, tf);
        }
        return tf;
    }
}

然后在setButtonFont内,从缓存中检索字体,而不是每次都直接从资源创建字体:

public static void setButtonFont(Button btn, String fontType){
    btn.setTypeface(TypefaceCache.getTypeface(btn.getContext, "fonts/" + fontType));
}

(您不需要activity参数,因为该按钮具有对上下文的引用。)

编辑:在考虑了这一点之后,我会建议使用以下版本的缓存:

public class TypefaceCache {
    private final static Map<String, SoftReference<Typeface>> cache
        = new HashMap<String, SoftReference<Typeface>>();

    private TypefaceCache() { /* do not allow instance creation */ }

    public static Typeface getTypeface(Context context, String path){
        synchronized (cache) {
            final SoftReference<Typeface> ref = cache.get(path);
            Typeface tf = ref == null ? null : ref.get();
            if (tf == null) {
                tf = Typeface.createFromAsset(context.getAssets(), path);
                cache.put(path, new SoftReference<Typeface>(tf));
            }
            return tf;
        }
    }
}

这有两个改进。首先,它在cache对象上同步,以便对getTypeface()的调用是线程安全的。 (如果你只是从UI线程调用这个方法,这可能不是那么重要。)其次,它允许自定义字体被垃圾收集,如果它们的唯一引用是在缓存本身。使用我建议的原始版本,只要应用程序进程存在,自定义字体就会保留在内存中,无论您是否仍然使用它们。