美文网首页
Android 设置字体

Android 设置字体

作者: 总是说下次 | 来源:发表于2017-11-22 10:27 被阅读647次

    吐槽

    首先,来点吐槽。在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:fontFamilyandroid: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,这些功能都不用了!!!再来欣赏一下我们想看数字体:

    wish_score.jpg

    相关文章

      网友评论

          本文标题:Android 设置字体

          本文链接:https://www.haomeiwen.com/subject/vgugvxtx.html