Android 字体使用探索

前言

之前开发时有使用到 TextView 或者绘图画文字的时候,并不会太在意文字的字体,因为设计给出的设计图都是比较普通的字体,今天在做一个新页面的时候,看到设计图中有部分地方的字体是不一样的,所以开始摸索下要怎样使用 Android 里的字体

官方文档

查阅官方的文档可以看到下面的信息

XML 中的字体

Android 8.0(API级别26)引入了一项新功能,即 XML 中的字体,它允许您将字体用作资源。您可以在 font 文件 res/font/ 夹中添加文件以将字体捆绑为资源。这些字体在您的 R 文件中编译,并在 Android Studio 中自动提供。我们可以借助新资源类型访问字体资源 font。例如,要访问字体资源,就可以使用 @font/myfont 或 R.font.myfont

要在运行 Android 4.1(API级别16)及更高版本的设备上使用字体 XML 功能,请使用支持库 26。有关使用支持库的更多信息,请参阅使用支持库

以上是文档开头的简介,接着往下看,可以看到,在 API level 26 或者以上时,只需简单的几步就可以使用字体资源:

如何使用

  1. 首先要创建一个字体资源文件夹:

  2. 然后创建好的目录如图:

    而项目里的字体资源文件放置在assets目录下:

    然后调用

    1
    2
    3
    4
    5
    6
    TypefaceManager 初始化...

    // TypefaceManager 中
    const val PRICE_TEXT_THIN = "fonts/DIN-Regular.otf"
    const val PRICE_TEXT_BOLD = "fonts/DIN-Bold.otf"
    const val PRICE_TEXT_MEDIUM = "fonts/DIN-Medium.otf"

    来进行使用,估计是版本兼容会更好,暂时还没深究原因

    双击放进去的字体资源文件就可以查看字体的预览:

  3. 然后就可以通过xml或者Java去设置字体

    1
    2
    3
    4
    5
    6
    //xml
    android:fontFamily="@font/merriweather_regular"

    //java
    Typeface typefaceLato = getResources().getFont(R.font.lato_regular);
    mTextIntro.setTypeface(typefaceLato);

    画文字的时候使用 paint 来设置字体,会有一些差别,暂时我还没怎么遇到,可以查看附在文末的相关文章

也可以指定一个基本的字体样式,如粗体,斜体或两者的组合

1
mTextIntro.setTypeface(typefaceLato,Typeface.BOLD_ITALIC);

如果使用的是字体系列,则会有相同的字体,权重不同有不同的效果

这里的权重可以去谷歌字体官方网站去查看,当你在官网选中了想要的字体之后,从下方的 Your Selection 中可以选择你要下载的字体,而旁边就有字体的权重,选择了相应权重后,右边会提示载入时间,当你选择过多的时候就会变成 Slow 而不是 Fast

值得注意的是,假设我正在使用 Merriweather-Regular,如果将字体样式设为粗体 Bold,Android 将从我的字体系列中选择 Merriweather-Bold,并显示出来

然后我也找到些stackoverflow上关于字体的问答,是关于预定义的,即系统中本来就有的一些字体的内容,如下:

From android 4.1 / 4.2 / 5.0, the following Roboto font families are available:

1
2
3
4
5
6
android:fontFamily="sans-serif"           // roboto regular
android:fontFamily="sans-serif-light" // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-black" // roboto black
android:fontFamily="sans-serif-thin" // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium" // roboto medium (android 5.0)

配合使用

1
android:textStyle="normal|bold|italic"

this 16 variants are possible:(有16种可用的变体)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Added in Android Jelly Bean (4.1) - API 16 :
Regular (default):
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">normal</item>

Italic:
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">italic</item>

Bold:
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">bold</item>

Bold-italic:
<item name="android:fontFamily">sans-serif</item>
<item name="android:textStyle">bold|italic</item>

Light:
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textStyle">normal</item>

Light-italic:
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textStyle">italic</item>

Thin :
<item name="android:fontFamily">sans-serif-thin</item>
<item name="android:textStyle">normal</item>

Thin-italic :
<item name="android:fontFamily">sans-serif-thin</item>
<item name="android:textStyle">italic</item>

Condensed regular:
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textStyle">normal</item>

Condensed italic:
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textStyle">italic</item>

Condensed bold:
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textStyle">bold</item>

Condensed bold-italic:
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textStyle">bold|italic</item>

Added in Android Lollipop (v5.0) - API 21 :
Medium:
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textStyle">normal</item>

Medium-italic:
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textStyle">italic</item>

Black:
<item name="android:fontFamily">sans-serif-black</item>
<item name="android:textStyle">italic</item>

<!-- 将字体封进style中 -->
<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
<item name="android:fontFamily">@font/lobster</item>
<item name="android:textStyle">normal</item>
</style>

除此之外,还可以创建自己的字体系列,步骤如下:

  • 右键单击字体文件夹,然后转到“ 新建”>“字体资源文件”。将出现“新建资源文件”窗口。
  • 输入文件名,然后单击“ 确定”。新的字体资源XML在编辑器中打开。

然后编写自己的字体系列,那么这里就用到权重了

1
2
3
4
5
6
7
8
9
10
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:fontStyle="normal"
android:fontWeight="400"
android:font="@font/lobster_regular" />
<font
android:fontStyle="italic"
android:fontWeight="400"
android:font="@font/lobster_italic" />
</font-family>

这只是将特定fontStyle和fontWeight映射到将用于呈现该特定变体的字体资源。fontStyle的有效值是normal、italic或bold, 而fontWeight需要符合CSS font-weight规范

注意事项

注意:通过支持库在XML布局中声明字体系列时,请使用app命名空间来确保加载字体。(谷歌官方文档)

注意:从Android Support Library 26.0开始,您必须声明两组属性(android:和app:),以确保在运行Api 26或更低版本的设备上加载字体。如下所示(stackoverflow)

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<font-family
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<font android:fontStyle="normal" android:fontWeight="400" android:font="@font/myfont-Regular"
app:fontStyle="normal" app:fontWeight="400" app:font="@font/myfont-Regular"/>
<font android:fontStyle="italic" android:fontWeight="400" android:font="@font/myfont-Italic"
app:fontStyle="italic" app:fontWeight="400" app:font="@font/myfont-Italic" />
</font-family>

系统字体的位置

1
D:\Android\sdk\platforms\android-N\data\fonts

fonts.xml里还可以配置字体的别名

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="font_family_light">sans-serif-light</string>
<string name="font_family_medium">sans-serif-medium</string>
<string name="font_family_regular">sans-serif</string>
<string name="font_family_condensed">sans-serif-condensed</string>
<string name="font_family_black">sans-serif-black</string>
<string name="font_family_thin">sans-serif-thin</string>
</resources>

可下载的字体

Android 8.0(API级别26)和 Android 支持库26引入了对API的支持,以便从应用程序请求字体,而不是将文件捆绑到APK或让APK下载字体。该功能可通过支持库26在运行 Android API 14 及更高版本的设备上使用

可下载字体功能具有以下优点:

  • 减少APK大小
  • 提高应用安装成功率
  • 改善整体系统健康状况,因为多个APK可以通过提供商共享相同的字体。这样可以节省用户的蜂窝数据,手机内存和磁盘空间。在此模型中,需要时通过网络获取字体。
    关于可下载字体

参考文章


Android 字体使用探索
https://enderhoshi.github.io/2018/11/14/Android 字体使用探索/
作者
HoshIlIlI
发布于
2018年11月14日
许可协议