如何获取应用于TextView上的字体名称

5
Textview label = (TextView) findViewById(R.id.item_title);
label.setText("Solve My Issue !");
Log.d("TAG","Font-Family : "+ String.valueOf(label.getTypeface()));

当我查看日志时,它返回Font-Family : android.graphics.Typeface@7f37f870

如何知道字体族名称?是否可能?


getTypeface() 方法返回 Typeface 类对象,请查看并使用其中的方法访问 TypeFace 中的属性。 - ρяσѕρєя K
我认为您错过了链接,请分享它。 - Minion Dave
2
我能否获取字体的确切名称? - Minion Dave
1个回答

10

getTypeface() 方法返回 label 的 Typeface,而这个 Typeface 实例是 Typeface 的一个静态字段 Map<String, Typeface> sSystemFontMap 的值。现在你得到了该值,通过反射可以获取 sSystemFontMap 这个 map,然后想要找到键,即字体的名称。

protected Map<String, Typeface> getSSystemFontMap() {
    Map<String, Typeface> sSystemFontMap = null;
    try {
        //Typeface typeface = Typeface.class.newInstance();
        Typeface typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL);
        Field f = Typeface.class.getDeclaredField("sSystemFontMap");
        f.setAccessible(true);
        sSystemFontMap = (Map<String, Typeface>) f.get(typeface);
        for (Map.Entry<String, Typeface> entry : sSystemFontMap.entrySet()) {
            Log.d("FontMap", entry.getKey() + " ---> " + entry.getValue() + "\n");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sSystemFontMap;
}

private static List<String> getKeyWithValue(Map map, Typeface value) {
    Set set = map.entrySet();
    List<String> arr = new ArrayList<>();
    for (Object obj : set) {
        Map.Entry entry = (Map.Entry) obj;
        if (entry.getValue().equals(value)) {
            String str = (String) entry.getKey();
            arr.add(str);
        }
    }
    return arr;
}

我进行了测试,List arr 包含以下字符串

sans-serif
tahoma
arial
helvetica
verdana

这并不奇怪,因为Android系统使用与上述五个名称相同的字体。(可能在不同的系统版本中有一些差异,欲了解更多信息,请前往/system/etc/fonts.xml

<family name="sans-serif">
    <font weight="100" style="normal">Roboto-Thin.ttf</font>
    <font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
    <font weight="300" style="normal">Roboto-Light.ttf</font>
    <font weight="300" style="italic">Roboto-LightItalic.ttf</font>
    <font weight="400" style="normal">Roboto-Regular.ttf</font>
    <font weight="400" style="italic">Roboto-Italic.ttf</font>
    <font weight="500" style="normal">Roboto-Medium.ttf</font>
    <font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
    <font weight="900" style="normal">Roboto-Black.ttf</font>
    <font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
    <font weight="700" style="normal">Roboto-Bold.ttf</font>
    <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
</family>
<!-- Note that aliases must come after the fonts they reference. -->
<alias name="sans-serif-thin" to="sans-serif" weight="100" />
<alias name="sans-serif-light" to="sans-serif" weight="300" />
<alias name="sans-serif-medium" to="sans-serif" weight="500" />
<alias name="sans-serif-black" to="sans-serif" weight="900" />
<alias name="arial" to="sans-serif" />
<alias name="helvetica" to="sans-serif" />
<alias name="tahoma" to="sans-serif" />
<alias name="verdana" to="sans-serif" />

从这个可以看出,sans-serif,tahoma,arial,helvetica和verdana都是一样的东西。它们是sans-serif字体族的不同名称。


它返回给我 sans-serif、tahoma、arial、helvetica 和 verdana,那这到底是什么意思呢? - Minion Dave
/system/etc/fonts.xml 文件中,Android 系统定义了这五个名称指向 'Roboto' 字体。因此总结一下,**该字体是 Roboto**。 - liao
1
有没有更简单的方法来做这件事?正如我在Typeface的官方文档中所看到的,不幸的是,没有叫做Typeface.NAME或Typeface.getName()的属性或方法。 - Ashok Bijoy Debnath
谢谢!这个工作得很好,但有一些警告。有没有办法解决这些警告?
  1. 无法解析字段 'sSystemFontMap' 在 Typeface.class.getDeclaredField("sSystemFontMap");
  2. 未经检查的转换:'java.lang.Object' 到 'java.util.Map<java.lang.String,android.graphics.Typeface>' 在 (Map<String, Typeface>) f.get(typeface);
- Fisher
这种简单的任务只能用这种方式来完成,真是太疯狂了。 - blimpse

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