吐槽
首先,来点吐槽。在Android O 之前设置字体是如此之……
1. 在assert资源中添加字体资源Wish_Score.TTF
2. 从assert资源中获取字体Typeface.createFromAsset(context.getAssets(), "Wish_Score.TTF");
3. 只能通过代码TextView.setTypeface()进行设置。
缺点:自定义字体只能通过动态代码设置; 每次读assert资源进行多余IO操作;
Font Resource
为了解决上面的问题,Google 在Android O的新增了新特性Fonts in XML,该功能允许开发者像使用图片资源一样,使用字体。只需要在res/font/
文件夹下,直接添加字体资源(myfont.TTF),Android Studio会在R文件中生成该字体资源的引用,并通过 @font/myfont
R.font.myfont
进行访问。
如果某种字体相关样式(加粗、倾斜等)有某种偏爱,我们还可以在res/font/
创建,根结点为 font-family的xml文件,组合各种样式成为一种新字体资源。
<?xml version="1.0" encoding="utf-8"?>
<!--my_fontfa_family.xml ->
<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>
这里解释一下Font \ Font family \ Typeface:
在手工印刷时代,把具有相同大小、粗细、字型的所有字符模型放在一个盒子里,称为一种Font,对于现在来说就是所有相同大小、粗细、字型字符集;
而TypeFace 与 Font family意思是一样的,是具有不同width、weight ,但是字型 相同的Font集。
感兴趣的可以看看TypeFace vs Font
添加资源后,在xml布局文件中通中android:fontFamily="@font/my_fontfa_family"
设置TextView字体;
在代码中Android O以上的可直接调用
getResources().getFont(R.font.wish_score)
获取字体,若要支持到Android api 16则需要依赖support-compat
(appcompat-v7中已依赖
ResourcesCompat.getFont(context, R.font.myfont);
注意:在TextView中的xml属性如果同时设置android:fontFamily
和android:typeface="normal"
,后者将会被忽略,两种属性之所存在是因为typeface是api 1中就有用于设置一些系统固定的字体(不能@font去引别的字体),fontFamily
是api 16才添加的,灵活性更高。
Downloadable Fonts
有了字体资源后,我们能方便的使用各种字体,然而Google考虑到某些字体被多个应用使用的情况,若每个app都添加该字体资源,则会导致磁盘资源的浪费,同时增加各apk的体积。为了优化 Google Play services version 11 以后,向其它应用程序提供字体下载服务的程序,Downloadable Fonts,其它应用程序需要某个字体时通过Google 提供的APIs可以快捷的获取该字体资源。字体资源可能存在本地也可能需要通过网络进行加载。
[图片上传失败...(image-715cdf-1511280689021)]
要在apk中使用可下载字体,可以通过以下两种途径:
通过动态代码调用:
1.声明一个用于字体请求的FontRequest
该请求需要至少三个参数,分别是:字体提供商指定的授权路径、包路径、字体查询名称。例如Google Fonts的三个值分别是:"com.google.android.gms.fonts","com.google.android.gms","name=Open Sans&weight=800&italic=1",其中查询名称的格式由字体提供规范。Google Fonts的查询格式
注意:如果字体是非预装的,或使用support-compat中的FontReuqest,则必需提供第四个参数:签名认证信息。
PS:老版本的系统预装的有normal (Droid Sans), serif (Droid Serif), and monospace (Droid Sans Mono)三种字体,可以直接使用也用不着Downloadable Fonts,我在Pixel1(系统版本8.1)测试, Google Fonts是预装好的,但是一般为了兼容我们会使用support-compat中的APIs,似乎签名认证是必要的!
如何添加签名信息呢?这是一个Google Fonts的例子
<resources>
<array name="com_google_android_gms_fonts_certs">
<item>@array/com_google_android_gms_fonts_certs_dev</item>
<item>@array/com_google_android_gms_fonts_certs_prod</item>
</array>
<string-array name="com_google_android_gms_fonts_certs_dev">
<item>
MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
</item>
</string-array>
<string-array name="com_google_android_gms_fonts_certs_prod">
<item>
MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
</item>
</string-array>
</resources>
2.添加字体资源请求结果回调: FontsContract.FontRequestCallback
or FontsContractCompat.FontRequestCallback
若成功能返回相关字体的Typeface
3.为字体请求执行提供一个带Looper的Handler
,为了避免UI卡顿,Looper不能是UI主线程的MainLooper.
请求代码如下:
FontRequest request = new FontRequest("com.example.fontprovider.authority",
"com.example.fontprovider", "my font", certs);
FontsContract.FontRequestCallback callback =
new FontsContract.FontRequestCallback() {
@Override
public void onTypefaceRetrieved(Typeface typeface) {
// Your code to use the font goes here
...
}
@Override
public void onTypefaceRequestFailed(int reason) {
// Your code to deal with the failure goes here
...
}
};
FontsContract.requestFonts(context, request, callback , handler);
第二种方式,通过创建字体资源xml获取字体:
在res/font 文件夹下创建字体资源,并配置好字体相关信息。像普通资源一样使用。
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
android:fontProviderAuthority="com.example.fontprovider.authority"
android:fontProviderPackage="com.example.fontprovider"
android:fontProviderQuery="example font"
android:fontProviderCerts="@array/certs">
</font-family>
注意:如果在布局中的首次对字体引用,可能会加长inflate时间,而导致黑屏。为了避免这种情况,可以在
AndroidManifest.xml
文件中用<meta-data /> 标签声明需要预加载的字体
<meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" />
在arrary.xml中把需要预装的字体放在一个数组中:
<array name="preloaded_fonts">
<item>@font/font1</item>
<item>@font/font2</item>
</array>
结语:support 版本不升26,这些功能都不用了!!!再来欣赏一下我们想看数
字体:

网友评论