精华内容
下载资源
问答
  • 如何在网页中用上自己下载字体
    2019-05-07 10:06:10

    在开发过程中市场会遇到需要特殊的字体,所谓的特俗字体就是常用字体库中不包含的字体。这时候,我们可以从网络上下载到我们需要的字体,然后引用到我们需要的网页中去。 
    我们可以用CSS来引用字体路径。 
    @font-face可以实现从服务器端加载字体,所有浏览器中使用的字体就可以不受本地字体的限制。@font-face真的不是什么新鲜玩意,早在2001年时就被提出来,只不过近两年才被各浏览器广泛支持。而且各浏览器支持的字体文件格式也可能不同,一般来说如下四种格式可覆盖所有浏览器。

    eot:该格式仅在老版本的IE中使用,浏览器兼容性查看http://caniuse.sinaapp.com/html/item/eot/index.html

    ttf:(TrueTypeFont)是Apple公司和Microsoft公司共同推出的字体文件格式,随着windows的流行,已经变成最常用的一种字体文件表示方式,支持的浏览器很多。浏览器兼容性查看http://caniuse.sinaapp.com/html/item/ttf/index.html

    svg:(Scalable Vector Graphics)该字体可能最早在IOS设备上被支持,没有ttf格式使用的广泛。浏览器兼容性查看http://caniuse.sinaapp.com/html/item/svg-fonts/index.html

    woff:(Web Open Font Format)是一种网页所采用的字体格式标准。此字体格式发展于2009年,现在正由W3C标准化,以求成为web字体的统一标准。浏览器兼容性查看http://caniuse.sinaapp.com/html/item/woff/index.html

    如何定义字体不在本文的介绍范围内,可以用一些软件来生成字体文件和各格式之间转换。定制字体需要有非常好的设计基础。

    如何使用自定义字体?

    第一步,在CSS中引入字体并给名字取一个合适的名字,如下 

    @font-face {font-family: "SourceHanSansCN_Normal";
        src: url('SourceHanSansCN-Normal.eot'); /* IE9 */
        src:
                url('SourceHanSansCN-Normal.eot?#font-spider') format('embedded-opentype'),
                url('SourceHanSansCN-Normal.woff') format('woff'),
                url('SourceHanSansCN-Normal.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
                url('SourceHanSansCN-Normal.svg') format('svg'); /* iOS 4.1- */
        font-weight: normal;
        font-style: normal;
    }


    font-family定义字体的名字,接下来的src是加载字体文件的位置,之所有有多个url就是因为浏览器兼容问题。

    第二步,使用刚刚定义的字体,如下 
    div { 
    font-family: SourceHanSansCN_Normal; 
    }

    更多相关内容
  • 1、下载所需要的字体,.ttf格式本文以(FZCYJ.ttf 为例) 2、在src下新建common文件,文件夹中包含以下文件 3、打开font.css @font-face { font-family: 'FZCYJ'; //重命名字体名 src: url('FZCYJ.ttf'); //引入...
  • 2、在应用程序- - -找到word图标,点击右键显示包内容- - -打开Contents文件夹- - -打开Resources文件夹- - -打开Fonts文件夹,将字体包复制到此文件夹下。 3、重启电脑。 4、再次打开仿宋_GB2312字体的word文档,...
  • 在网上寻找无果,经测,在控制面板->外观和个性化->字体->字体设置中允许使用快捷方式安装字体勾选后仍然无法解决,于是打开regedit注册表编辑器进入计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\...
  • 在iOS的开发中经常遇到需要使用一些自定义的字体文件,比如仿宋_GB2312、方正小标宋_GBK等。之前我们为了使用这些自定义的字体,在...下面就iOS中使用字体的这两种方式进行介绍。 使用静态字体 1、将字体文件拷贝到

    在iOS的开发中经常遇到需要使用一些自定义的字体文件,比如仿宋_GB2312、方正小标宋_GBK等。之前我们为了使用这些自定义的字体,在应用的资源包中放入这些字体文件。因为字体文件通常比较大,有的一个字库就达到10M以上(拿方正小标宋_GBK这个字库来说就有13M之多),这样打包后的ipa文件的体积就可能会变得很大,对于只有个别的模块需要特殊的字体样式的应用来说很不划算,那么在iOS6.0以后苹果就开放了动态加载字体的权限。下面就iOS中使用字体的这两种方式进行介绍。

    使用静态字体

    1、将字体文件拷贝到项目工程中,在Info.plist文件中添加Fonts provided by application的配置项,其中每一个Item对应的是字体文件的名称,如DS-DIGI.TTF。

    2、使用时直接按照如下方式即可:

    _textLabel1.font = [UIFont fontWithName:@"DS-Digital" size:40];

    效果如下:

    3、其他说明:

    + (UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize;这个方法中需要指定的fontName不是前面设置的字体文件的文件名,而应该是字体的名称,如何获取字体的名称可以通过如下方式:

    (1)打印出当前所有可用的字体,查找对应的字体名称

    - (void)printAllFonts {
    
        NSArray *fontFamilies = [UIFont familyNames];
    
        for (NSString *fontFamily in fontFamilies) {
            NSArray *fontNames = [UIFont fontNamesForFamilyName:fontFamily];
            NSLog (@"%@: %@", fontFamily, fontNames);
        }
    
    }

    (2)通过Mac自带的字体册查看字体的名称

    直接双击字体即可打开字体册,如果系统没有安装该字体按照要求安装即可,然后可以在字体的详细信息中找到对应的字体的名称:

    使用动态字体

    1、动态下载自定义的字体

    在网易新闻iOS客户端中可以使用自定义的字体,对于未下载的字体可先下载然后安装下次就能自动设置为该字体,效果如下:

    下面就该功能简单介绍实现的步骤

    (1)下载指定的字体文件到本地

    第一次进入该页面会自动到服务器上获取可使用的字体的列表,示例如下:

    [{
    "fontTitle": "华康圆体",
    "regularName": "DFYuanW3-GB",
    "boldName": "DFYuanW5-GB",
    "author": "华康科技",
    "date": "2012-10-11",
    "fileUrl": "http://xxxx/font/dfgb_y.zip",
    "fileSize": "3.3MB",
    "previewUrl": "http://yyyy/font/ios_yuanti.png"
    }]

    上面的内容指明了字体的名称,下载地址等信息,从上面的内容可以看出下载回来的字体文件是一个zip压缩包,再使用前还需要进行解压处理。

    1)下载字体文件

    - (NSString *)downloadZipFile:(NSString *)fileUrl toPath:(NSString *)path {
    
        NSError *error = nil;
        NSURL *url = [NSURL URLWithString:fileUrl];
        NSString *fileName = [url lastPathComponent];
        NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
    
        if(!error) {
    
            NSString *zipPath = [path stringByAppendingPathComponent:fileName];
            [data writeToFile:zipPath options:0 error:&error];
            if(!error) {
                return zipPath;
            }
        }
        return nil;
    }

    2)解压zip压缩包

    iOS中解压zip压缩文件非常方便,使用ZipArchive这个开源项目按照如下的方式即可快速解压zip文件。

    - (NSString *)expandZipFile:(NSString *)src toPath:(NSString *)desc {
    
        ZipArchive *za = [[ZipArchive alloc] init];
    
        if ([za UnzipOpenFile:src]) {
    
            BOOL ret = [za UnzipFileTo:desc overWrite:YES];//解压文件
            if(ret){
                NSString *zipName = [src lastPathComponent];//获取zip文件的文件名
                [[NSFileManager defaultManager] removeItemAtPath:zipPath error:nil];//删除zip压缩包
                zipName = [zipName substringToIndex:[zipName rangeOfString:@".zip"].location];//获取解压到的文件夹
                return [self.downloadPath stringByAppendingPathComponent:zipName];
            }
        }
    
        return nil;
    }

    ZipArchive项目地址:https://github.com/mattconnolly/ZipArchive

    (2)注册指定路径下的字体文件

    下载回来的字体文件如果不做处理是不能直接使用的,使用前需要先注册然后才能使用,注册方式如下:

    需要先引入#import <CoreText/CoreText.h>,CoreText框架。
    - (void)registerFont:(NSString *)fontPath {
    
        NSData *dynamicFontData = [NSData dataWithContentsOfFile:fontPath];
        if (!dynamicFontData){
            return;
        }
    
        CFErrorRef error;
        CGDataProviderRef providerRef = CGDataProviderCreateWithCFData((__bridge CFDataRef)dynamicFontData);
        CGFontRef font = CGFontCreateWithDataProvider(providerRef);
        if (! CTFontManagerRegisterGraphicsFont(font, &error)){
            //注册失败
            CFStringRef errorDescription = CFErrorCopyDescription(error);
            NSLog(@"Failed to load font: %@", errorDescription);
            CFRelease(errorDescription);
        }
        CFRelease(font);
        CFRelease(providerRef);
    }
    
    // 注册方式2,使用URL
     NSString *imgFilePath = [filePath path];
     NSURL *fontUrl = [NSURL fileURLWithPath:imgFilePath];
     CGDataProviderRef fontDataProvider =  CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);
     CGFontRef fontRef = CGFontCreateWithDataProvider(fontDataProvider);
     //the next line is relevant part
     [UIFont familyNames];
     CGDataProviderRelease(fontDataProvider);
     CTFontManagerRegisterGraphicsFont(fontRef, NULL);
     NSString *fontName = CFBridgingRelease(CGFontCopyPostScriptName(fontRef));
     label.font = [UIFont fontWithName:fontName size:24];
    

    在调用注册CTFontManagerRegisterGraphicsFont前最好调下[UIFont familyNames];苹果内部的一个bug.

    ios - CGFontCreateWithDataProvider hangs in airplane mode - Stack Overflow

    (3)判断字体是否加载

    在使用字体文件前最好是先判断字体是否已经被加载过了,判断方式如下:

    - (BOOL)isFontDownloaded:(NSString *)fontName {
    
        UIFont* aFont = [UIFont fontWithName:fontName size:12.0];
        BOOL isDownloaded = (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame));
        return isDownloaded;
    }

    (4)其他说明

    经测试注册过的字体在应用关闭后下次开启应用,判断字体是否加载时返回为NO,为了保证正常使用需要每次启动应用的时候先遍历一遍字体文件夹将里面的字体文件都再次注册一遍即可。参考代码如下:

        //注册fonts目录下面的所有字体文件
        NSArray *ary = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.downloadPath error:nil];
        for (NSString *p1 in ary) {
            NSString *t1 = [self.downloadPath stringByAppendingPathComponent:p1];
            NSArray *ary1 = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:t1 error:nil];
            for (NSString *p1 in ary1) {
    
                NSString *t2 = [t1 stringByAppendingPathComponent:p1];
                if([t2 rangeOfString:@".ttf"].location != NSNotFound) {
                    [self registerFont:t2];
                }
            }
        }

    2、动态下载苹果提供的字体

    大多数的中文字体是有版权的,在应用中加入特殊中文字体还需要处理相应的版权问题。从iOS6开始,苹果就支持动态下载中文字体到系统中。

    (1)苹果支持下载的字体列表

    1)iOS6字体列表:http://support.apple.com/zh-cn/HT202599

    2)iOS7字体列表:http://support.apple.com/zh-cn/HT5878

    (2)官方提供的示例代码

    访问https://developer.apple.com/library/ios/samplecode/DownloadFont/Introduction/Intro.html下载示例程序。针对示例程序简单介绍如下:

    1)判断字体是否已经被下载过

    UIFont* aFont = [UIFont fontWithName:fontName size:12.];
    
    if (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame)) {
    // 字体已经被加载过,可以直接使用
    return;
    
    }

    2)下载字体

        // 根据字体的PostScript名称构建下载字体所需的参数:
    
        //使用字体的PostScript名称构建一个字典
        NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName, kCTFontNameAttribute, nil];
        //根据上面的字典创建一个字体描述对象
        CTFontDescriptorRef desc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attrs);
    
        //将字体描述对象放到一个数组中
        NSMutableArray *descs = [NSMutableArray arrayWithCapacity:0];
        [descs addObject:(__bridge id)desc];
        CFRelease(desc);
    
        // 下载字体文件:
        _block BOOL errorDuringDownload = NO;
        CTFontDescriptorMatchFontDescriptorsWithProgressHandler( (__bridge CFArrayRef)descs, NULL,  ^(CTFontDescriptorMatchingState state, CFDictionaryRef progressParameter) {
            //下载的进度
            double progressValue = [[(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingPercentage] doubleValue];
    
            if (state == kCTFontDescriptorMatchingDidBegin) {
                dispatch_async( dispatch_get_main_queue(), ^ {
                    //开始匹配
                    NSLog(@"Begin Matching");
                });
    
            } else if (state == kCTFontDescriptorMatchingDidFinish) {
    
                dispatch_async( dispatch_get_main_queue(), ^ {
                    if (!errorDuringDownload) {
                        //字体下载完成
                        NSLog(@"%@ downloaded", fontName);
                        //TODO:在此修改UI控件的字体样式
                    }
    
                });
    
            } else if (state == kCTFontDescriptorMatchingWillBeginDownloading) {
    
                //开始下载
                 NSLog(@"Begin Downloading");
                 dispatch_async( dispatch_get_main_queue(), ^ {
                    //TODO:在此显示下载进度提示
                });
    
            } else if (state == kCTFontDescriptorMatchingDidFinishDownloading) {
    
                //下载完成
                NSLog(@"Finish downloading");
                dispatch_async( dispatch_get_main_queue(), ^ {
                    //TODO:在此修改UI控件的字体样式,隐藏下载进度提示
                });
    
            } else if (state == kCTFontDescriptorMatchingDownloading) {
    
                //正在下载
                NSLog(@"Downloading %.0f%% complete", progressValue);
                dispatch_async( dispatch_get_main_queue(), ^ {
                    //TODO:在此修改下载进度条的数值
                });
    
            } else if (state == kCTFontDescriptorMatchingDidFailWithError) {
    
                //下载遇到错误,获取错误信息
                NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError];
                NSLog(@"%@", [error localizedDescription]);
                //设置下载错误标志
                errorDuringDownload = YES;
            }
    
                return YES;
    
        });

    (3)说明

    1)使用动态下载中文字体的API可以动态地向iOS系统中添加字体文件,这些字体文件都是下载到系统的目录中(目录是/private/var/mobile/Library/Assets/com_apple_MobileAsset_Font/),所以并不会造成应用体积的增加,而且可以在多个应用中共享。

    2)如何获取字体的PostScript和FontName?可以通过Mac系统自带的字体册来查看。具体请参考前面的步骤。

    展开全文
  • 一个导出excel的demo,包含导出的逻辑代码和依赖包,下载以后请执行 npm install ,然后起服务访问,不能直接以 file://打开
  • Android中使用可下载字体

    千次阅读 2020-03-03 17:30:50
    下载字体简介 在Android 8.0(API level 26)和Android Support库26开始提供了从字体提供商下载字体的API接口,用以替代将字体绑定打包到APK文件中,或者让APK下载字体文件。这个功能在Android 8.0(API level 26...

    可下载字体简介

    在Android 8.0(API level 26)和Android Support库26开始提供了从字体提供程序下载字体的API接口,用以替代将字体绑定打包到APK文件中,或者让APK下载字体文件。这个功能在Android 8.0(API level 26)及以上版本系统可用,或者在API level 14及以上的系统,通过26及以上版本的Support库实现。

    可下载字体功能有一下好处

    • 降低APK文件大小
    • 提高应用安装成功率
    • 多个APK可以通过提供程序共享相同的字体,在需要的时候才从提供程序获取,这样可以改善系统生态的健康,节省用户移动设备的数据,内存以及硬盘存储空间。

    更多相关内容可参考Google 官方文档

    可下载字体如何实现?

        字体提供器是能将字体缓存到本地的应用,其他应用就可以请求和共享字体,大致的逻辑流程下图所示:
    图1:可下载字体的处理流程

    可下载字体实现方法

    可下载字体的实现方法有以下几种

    • 通过AndroidStudio和Google Play服务框架实现;
    • 通过代码编程实现;
    • 通过support支持库实现。

    通过AndroidStudio和Google Play服务框架实现可下载字体

    通过Android Studio 3.0及以上版本,可为应用配置下载字体。另外可使用Google Play服务框架的字体提供器,入门可下载字体功能。

    注意:设备必须有11及以上版本的Google服务框架,才能使用Google字体提供器。

    使用步骤如下:

    1. 打开布局文件,在布局编辑器(Layout Editor)中,切换为设计(Design)页面,点击选中需要设置字体的TextView控件,然后在属性(Attributes)窗口中,依次展开All Attributes>fontFamily>More Fonts,打开字体资源选择器
      Layout Editor
    2. 在选择器页面的Source选择Google Fonts
      Font Resources
    3. 在选择对应的字体(选择Downloadable Fonts中的字体),选择字体样式,点击“OK”按钮即可。

    Android Studio会自动生成需要渲染的字体描述XML文件,并添加应用中。
    自动生成的字体描述XML文件
    4. 预览字体文件

    通过编程实现可下载字体功能

        从Android 8.0(API level 26)开始,系统直接支持可下载字体,但是在之前的版本,则需要使用26.0及以上版本的支持库来实现。

        编程方式实现可下载字体功能,你需要掌握两个关键的类

    • android.graphics.fonts.FontRequest:这个类可以创建一个字体请求
    • android.provider.FontsContract:这个类可以可以基于字体请求创建一个字体样式(Typeface)对象

        你的应用通过FontsContractAPI从提供器中索引字体。每个字体提供程序对Android版本和支持的语言都有一套自己的限制,详情需要参考字体提供程序的相关文档。

    下载字体,按一下步骤实现:

    1. 创建一个android.graphics.fonts.FontRequest类的对象,用来想提供程序请求字体。创建一个请求,需要传入以下参数:
    • 字体提供程序的认证
    • 用来区分提供程序的字体提供程序包名
    • 字体查询索引
    • 用以验证提供程序身份的证书哈希值列表

    示例:

    val fontRequest = FontRequest(
        "com.google.android.gms.fonts",
        "com.google.android.gms",
        "Aclonica",
        R.array.com_google_android_gms_fonts_certs)
    

    证书哈希值列表在XML资源中定义

    <?xml version="1.0" encoding="utf-8"?>
    <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>
    

    注意:如果您从系统预安装的提供程序中请求字体,则无需添加证书。但是,如果通过支持库请求字体,则必须提供证书。

    1. 创建FontsContract.FontRequestCallback类的实例

    2. 覆盖 onTypefaceRetrieved()方法 :这是字体请求已完成的回调方法,检索到的字体作为回调参数,您可以根据需要在此方法设置字体。例如,您可以在TextView设置字体样式

    3. 重写 onTypefaceRequestFailed() 方法:这字体请求过程中出现错误的回调方法。有关错误代码的更多信息,请参阅 error code constants

    4. 调用FontsContract.requestFont()方法重字体提供程序中获取字体内容。这个方法将检查字体是否存在缓存中,如果字体不在本地缓存,将会从字体提供程序中异步下载字体。调用该方法传入以下参数:

    • Context类对象
    • android.graphics.fonts.FontRequest类对象
    • 用户监听请求结果的回调(FontsContract.FontRequestCallback对象)
    • 字体下载线程的处理程序(Handler对象)

    代码示例:

    val fontRequest = FontRequest(
        "com.google.android.gms.fonts",
        "com.google.android.gms",
        "Aclonica",
        R.array.com_google_android_gms_fonts_certs)
    
    
    val requestCallbacks = object : FontsContract.FontRequestCallback() {
    
        override fun  onTypefaceRetrieved(typeface: Typeface) {
            Log.e("AAAAAA", "onTypefaceRetrieved: ${typeface.toString()}")
            typeFace = typeface
            FontRequestManager.instance.onTypefaceRetrieved("Aclonica", typeface)
        }
    
        override fun onTypefaceRequestFailed(reason: Int) {
            Log.e("AAAAAA", "onTypefaceRequestFailed: ${reason}")
        }
    }
    
    FontsContract.requestFont(this, fontRequest, requestCallbacks, mHandler)
    

    通过支持库使用可下载字体

         26及以上版本的支持库,为运行Android API版本低于26且大于14的设备上提供可下载字体的功能的支持。android.support.v4.provider包名下包含了相关的类,支持库中相关的类跟系统框架中的类似,下载字体的流程也跟前面提到的系统框架下载字体类似。

    支持库与系统框架类对应关系

    系统框架中的类支持库中的类备注
    android.provider.FontRequestandroidx.core.provider.FontRequest-
    android.provider.FontsContractandroidx.core.provider.FontsContractCompat-

    使用支持库实现可下载字体的功能,也就是使用支持库中的androidx.core.provider(或者是android.support.v4.provider)包下的类替换系统框架中的android.provider包下的类。

    注意:通过支持库实现可下载字体功能,即使字体提供程序是系统预安装的,在你请求字体的时候,必须提供证书。

    在项目中添加依赖库的支持

    在项目中添加com.android.support:support-compat的依赖(如果targetSDKVersion是28及以上,可以使用androidx.core:core依赖)

    通过XML资源来定义使用可下载字体

    在Android 8.0 (API level 26)及26的支持库开始,提供了一种更有效方法声明自定义的字体,那就是通过XML资源文件。这就意味着不在需要将字体打包到程序的asset资源中,如果字体支持支持,还可以轻松设置自定义字体的主题样式,比如:字体粗细。

    1. res/font目录下创建XML文件
    2. 在XML文件中添加<font-family>根节点,跟字体相关的属性如下示例XML文件所示:
    <?xml version="1.0" encoding="utf-8"?>
    <font-family xmlns:app="http://schemas.android.com/apk/res-auto"
        app:fontProviderAuthority="com.google.android.gms.fonts"
        app:fontProviderCerts="@array/com_google_android_gms_fonts_certs"
        app:fontProviderPackage="com.google.android.gms"
        app:fontProviderQuery="Aclonica">
    </font-family>
    
    1. 通过@font/xml_font_file_name的方式引用字体文件,可以在XML布局文件中直接引用,也可以在代码中使用getFont()方法获取字体文件。

    AndroidManifest.xml中预声明字体

    在布局中关联字体和检索下载是异步任务。第一次尝试检索字体会默认请求字体提供程序,因此会增加第一次布局加载时间,为避免延迟,你可以在AndroidManifest.xml预声明需要检索的字体。在系统从提供程序中获取到字体后,将会立即可用。如果字体获取使用的事件超过了期望,系统将会中断获取进程,并使用默认的字体。

    在清单中预声明字体的步骤如下:

    1. 在资源目录res/values下创建一个数组资源xml文件,,并在里面列出需要预定义的字体
      示例:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <array name="preloaded_fonts" translatable="false">
            <item>@font/aclonica</item>
            <item>@font/alex_brush</item>
            <item>@font/bilbo_swash_caps</item>
        </array>
    </resources>
    
    1. AndroidManifest.xml中使用meta-data标签声明预定义的字体数组
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- .... -->
        <application>
            <!-- .... -->
            <meta-data
                android:name="preloaded_fonts"
                android:resource="@array/preloaded_fonts" />
        </application>
    
    </manifest>
    

    添加证书

    如果字体提供程序不是预安装,或者如果你使用支持库实现,那么你就必须声明字体提供程序验证使用的签名证书,系统使用该证书校验字体提供程序的身份。

    注意:如果你使用Android Studio的字体选择工具选择Google Play服务框架提供程序中的字体,Android Studio会自动配置证书。

    添加证书的步骤如下:

    1. 创建一个包含证书详细内容的字符数组资源
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <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>
    
    1. 在字体配置文件中的fontProviderCerts节点配置证书
    <?xml version="1.0" encoding="utf-8"?>
    <font-family xmlns:app="http://schemas.android.com/apk/res-auto"
            app:fontProviderAuthority="com.google.android.gms.fonts"
            app:fontProviderPackage="com.google.android.gms"
            app:fontProviderQuery="Alex Brush"
            app:fontProviderCerts="@array/com_google_android_gms_fonts_certs_prod">
    </font-family>
    

    说明:如果提供程序包含多个证书,可以定义一个数组,数组的元素就是包含证书的字符数组

    <?xml version="1.0" encoding="utf-8"?>
    <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>
    

    经验总结

        可下载字体是一个很好的策略,但是由于国内手机厂商比较多,没有一个统一的Android手机生态(众所周知的原因,Google Play服务国内无法使用),所以必须自己搭建一套字体提供程序,这样一来也是相当繁琐的。这个功能也是从Android 8.0(API 26)才开始提出(但可以通过支持库在Android 4.0(API 14)及以上版本使用),如果有兴趣的同学,还可以学些搭建自己的字体提供程序。

    展开全文
  • Android 自定义和可下载字体

    千次阅读 2018-05-29 10:09:49
    原文:Custom and Downloadable Fonts on Android 作者:Ivan Kust 译者:kmyhy Android 一开始的时候,没有使用自定义字体的开箱即...最近,Google 为 Android 8.0 推出了自定义和可下载字体。他们还通过Sup...

    原文:Custom and Downloadable Fonts on Android
    作者:Ivan Kust
    译者:kmyhy

    Android 一开始的时候,没有使用自定义字体的开箱即用解决方案。设备上只能使用少部分预装字体。

    你必须要做一些创新,并为这种小事情编写大量的代码。

    最近,Google 为 Android 8.0 推出了自定义和可下载字体。他们还通过Support Library 版本 26 提供了对早期 Android 版本的支持。

    在本教程中,你将通过创建一个简单的 demo 来了解如何使用它们。在此过程中,您将学习:

    • 如何为 app 添加自定义字体
    • 如何定义字族
    • 如何从提供者添加一个可下载字体
    • 如何检索字体学习

    让我们开始吧!:]

    注:本教程假设你了解用 Kotlin 开发 Android 程序的基础。如果你是一个新手,可以看一下我们的 Kotlin 入门教程。如果你是 Android 开发新手,请先看看我们的 Android教程

    历史:不一样的过去

    一直到最近,要在视图上使用自定义字体,必须进行以下操作:

    1. 将字体文件放到 assets 文件夹
    2. 从 asset 文件将字体加载为 Typeface 对象
    3. 用 setTypeface() 设置视图的 Typeface

    这种方式的主要缺点在于你在布局文件中设置字体——你只能使用代码:

    val myTypeface = Typeface.createFromAsset(assets, "fonts/myFont.ttf")
    myTextView.typeface = myTypeface

    要解决这种情况,你可以扩展这个视图类并添加一个自定义属性,用于从布局中传递字体文件。这是很好,但仍然存在一些问题:

    • 你必须扩展每个想使用自定义字体的 View
    • 有的设备加载 assets 时会花很长时间,因此你必须将字体缓存到内存中
    • 某些情况下会出现问题——例如如果你必须修改 toolbar 上的字体时

    更不必说,仅仅为了设置一个自定义字体就必须扩展一个 TextView 的感觉很不好。

    开始

    前提条件

    要使用自定义字体,首先必须安装最新的 AndroidStudio3.x。这一点很重要,因为 AndroidStudio2.x 不支持某些特性,例如字体资源目录。

    安装 AndroidStudio 时,请按照我们在 Android 开发教程中所说的去做。

    您的第一个任务是切换到最新的支持库。您可以在这里下载开始项目

    打开 AndroidStudio 并用 File\Open 导入开始项目。选择开始项目的解压缩位置,然后单击对话框上的 Open。

    当项目打开并同步时,build& run。

    你会看到一个简单的 Font Quiz app。如果你开始答题,你会被提 5 个问题,让你猜出文本所用的字体。

    等等——这些文字显示的都是同一个(默认)字体!我们后面会解决这个问题。首先来添加一个最新支持库。

    添加最新支持库

    打开 \app 文件夹下的 build.gradle 文件(在 Android project 视图中,你可以在 Gradle Scripts 文件夹下找到它),然后修改其中的 dependecies{…} 一行:

    implementation ‘com.android.support:support-v4:27.0.2’

    这将添加最新版本的 Android 支持库,该支持库将使 API 14 以后支持自定义字体和可下载字体。

    您还需要将 compileSdkVersion 和 targetSdkVersion 更改为27。最后,将 other support library dependencies(即 appcompat 和 design) 更改为27.0.2版本。

    然后,点击编辑器窗口顶端 gradle 通知中的 Sync now。

    当 gradle 同步完,build & run,看看是否正常:

    看起来没有任何改变,但是我们已经为自定义字体的添加做好了准备!

    把字体打包

    谷歌在 Android 8 推出了字体资源的新特性。将字体文件放入res\fonts 文件夹中,就能将其已资源方式打包到 .apk 中。这些字体会编译到 R 文件中,同时可以在 Android Studio 中可以像字符串、drawable 和 color 资源一样使用。

    注:字体资源只能在 Android Studio 3.x 中使用,而不能在 2.x 中使用。

    接下来你要做的就是给应用程序添加一个自定义的 .ttf 字体。在这里下载OpenSans-regular 字体。

    回到 Android Studio,选择 project 导航器中的 Android:

    点击 res 文件夹,按 cmd+N(或者 File\New)然后选择 Directory。

    弹出一个对话框,要你输入目录名,输入 font:

    现在,右键单击新目录,然后单击“在Finder中显示”(MacOS)、“在资源管理器中显示”(Windows)或“在文件中显示”(Linux)。将下载的 OpenSans-Regular.ttf 文件移到您打开的字体文件夹中,并将其重命名为opensans_regular.ttf。在Android资源名只能使用字母数字和下划线。

    回到 Android Studio 并打开res\layout\activity_main.xml文件。找到id 为 tvFonQuiz 的 AppCompatTextView。向其添加以下属性:

    app:fontFamily="@font/opensans_regular"
    

    text view 的布局代码现在是这个样子:

    <android.support.v7.widget.AppCompatTextView
      android:id="@+id/tvMessage"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/quiz_message"
      android:textAlignment="center"
      app:fontFamily="@font/opensans_regular"
      app:layout_constraintBottom_toTopOf="@+id/startButton"
      app:layout_constraintLeft_toLeftOf="parent"
      app:layout_constraintRight_toRightOf="parent"
      app:layout_constraintTop_toTopOf="parent" />

    Build & run。

    你可以看到文字消息变成了 OpenSans 字体。真简单!

    创建字族

    另一个新功能是,您可以创建字族,用于包含一系列字体文件,以及它们的样式和字重。要创建一个新的字族,您实际上需要创建一个新的 XML 字体资源。好处是您可以作为一个整体访问它,而不是将每个样式和字重的单个字体文件引用为单独的资源。

    你现在可以创建一个新字族。首先,来创建 OpenSans 的粗体

    重复上面的步骤,将新的字体文件添加到项目的字体文件夹中。将文件重命名为opensans_bold.ttf。

    接下来创建一个字族资源。

    点击 res\font 文件夹,按 ⌘N (或者 File\New) 并选择 Font resource file。

    在 File name 栏输入 opensans 然后点击 OK。

    Android studio 会生成一个空的字族资源:

    <?xml version="1.0" encoding="utf-8"?>
    <font-family xmlns:android="http://schemas.android.com/apk/res/android">
    
    </font-family>

    用 标签添加两个字体文件到字族中。这个标签有 3 个属性:

    • font: 字体文件的资源 ID
    • fontStyle: 字体文件的风格,可以是 normal 或 italic
    • fontWeight: 字重

    为了添加 regular 和 italic 字体,你需要用两个 元素:

    <?xml version="1.0" encoding="utf-8"?>
    <font-family xmlns:android="http://schemas.android.com/apk/res/android">
      <font
          android:fontStyle="normal"
          android:fontWeight="400"
          android:font="@font/opensans_regular" />
      <font
          android:fontStyle="italic"
          android:fontWeight="400"
          android:font="@font/opensans_bold" />
    </font-family>

    注意,为了向后兼容 8.0 以下 Android 版本,还必须以命名空间 app 来声明所有字体属性。这将使用支持库的自定义字体实现。添加它们之后,您的资源文件应该如下所示:

    <?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:font="@font/opensans_regular"
            android:fontStyle="normal"
            android:fontWeight="400"
            app:fontFamily="@font/opensans_regular"
            app:fontStyle="normal"
            app:fontWeight="400" />
        <font
            android:font="@font/opensans_bold"
            android:fontStyle="italic"
            android:fontWeight="400"
            app:font="@font/opensans_bold"
            app:fontStyle="italic"
            app:fontWeight="400" />
    </font-family>

    现在回到 res/layout/activity_main.xml 修改 tvMessage 的 app:fontFamily 属性为 opensans:

    <android.support.v7.widget.AppCompatTextView
      android:id="@+id/tvMessage"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/quiz_message"
      android:textAlignment="center"
      app:fontFamily="@font/opensans"
      app:layout_constraintBottom_toTopOf="@+id/startButton"
      app:layout_constraintLeft_toLeftOf="parent"
      app:layout_constraintRight_toRightOf="parent"
      app:layout_constraintTop_toTopOf="parent" />

    Build & run。

    在布局中使用自定义字体

    在前面的步骤中,您已经看到了如何向 TextView 添加自定义字体。现在,您将向主题添加自定义字体,更改所有使用该主题的 activity 的默认字体。

    打开文件 res/values/styles.xml。

    修改 app 的 Theme.FontQuiz ——加入 fontFamily 属性:

    <style name="Theme.FontQuiz" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="fontFamily">@font/opensans</item>
    </style>

    Build & run。

    您可以看到在整个应用程序中都使用了 OpenSans:

    在代码中使用自定义字体

    您也可以通过代码来设置自定义字体。为此,您将用到支持库中的 ResourcesCompat 类。在 MainActivity 的 onCreate()方法的末尾输入:

    val typeface = ResourcesCompat.getFont(this, R.font.opensans_bold)
    startButton.typeface = typeface

    Build & run。

    你可以看到开始按钮被设置为 OpenSans 粗体。

    注意,您使用支持库来支持小于 Android 8.0 的版本。

    可下载字体

    你已经了解了自定义字体的工作方式,那么让我们跳到另一个新知识点,可下载字体。可下载字体允许你按需下载或在应用程序启动时向应用程序添加字体。

    它还有其它好处:

    • 只在需要时才下载字体
    • 减少 apk 的大小
    • 通过字体提供者在多个 app 共享字体

    字体提供者的机制

    字体提供者负责检索和缓存跨应用程序使用的可下载字体。请求字体的过程如下:

    所有使用可下载字体的应用程序都通过 FontsContractCompat 传递它们的请求。然后,它与请求的字体提供者进行通信。字体提供者是负责获取和缓存适当字体的应用程序。可以在设备上安装多个字体提供者,但目前只有 Google 字体提供者可用。

    安全和证书

    为了在使用字体提供者时确保安全,你必须提供字体提供者的签名证书。这样 Android 才能够校验字体提供者的身份。你必须在设备未预安装的字体提供者时或使用支持库时这样做。

    接下来的任务是添加 Google 字体提供者的证书。

    点击 res\values 文件夹,按 ⌘N (或 File\New) 并选择 Values resource file。

    在对话框中,命名为 font_certs 然后点 Ok。

    以字符串数组的形式指定字体提供者证书。如果字体提供者有多个证书集,则必须定义一个字符串数组的数组。支持库所用的 Google 字体提供者使用两组证书,下一步是为每个组证书定义一个数组。

    在新文件中添加一个字符串数组,在“”节中添加一个 ,命名为 com_google_android_gms_fonts_certs_dev。

    为它添加一个 item,内容如下:

    <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 arry,名为 com_google_android_gms_fonts_certs_prod 然后为它添加一个 item ,内容如下:



    <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>

    最后,创建一个数组,名为 com_google_android_gms_fonts_certs,将之前定义的两个 string arrays 作为其 item.

    你的 font_certs.xml 文件变成这个样子:

    <?xml version="1.0" encoding="utf-8"?>
    <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>
                MIIEqDCCA5CgAwIBA…
            </item>
        </string-array>
        <string-array name="com_google_android_gms_fonts_certs_prod">
            <item>
                MIIEQzCCAyugAwIBAgIJAMLgh0…
            </item>
        </string-array>
    </resources>

    Build & run。

    没有任何变化,但已经为可下载字体准备好了。

    在代码中使用可下载字体

    FontQuiz app 还缺少一个重要的功能——问题中的文本应该只使用提问到的字体。

    你可以用一个请求来获取可下载的字体,并将它们以代码方式应用到 View 中。必须使用支持库中的 FontsContractCompat 类来支持 8.0 以下的 Android 版本。

    你的任务将是使用它来请求和设置一个随机字体的问答页面。

    打开 QuestionActivity 的 showFont() 方法。

    用于测验的字族名位于 res\value\family_names.xml 文件中的一个 list 中。选择一个随机字体的问题和对应 4 个选项的代码已经写好。你的任务是请求并显示传递给 showFont() 的字体。

    首先,隐藏所有按钮并显示一个 ProgressView,表示字体正在被加载:

    buttons.forEach { button -> button.isEnabled = false }
    progressView.visibility = View.VISIBLE

    Build & run。

    点击 “Start Quiz” ,当第一个问题出来时,你会看到所有按钮禁用,加载进度显示。

    接下来该创建字体请求。

    创建一个字体请求

    接下来的任务是添加一个请求用于下载字体到 QuestionActivity。

    创建一个 query 字串,以及一个可下载字体的请求:

    val query = "name=$familyName"
    val request = FontRequest(
      "com.google.android.gms.fonts",
      "com.google.android.gms",
      query,
      R.array.com_google_android_gms_fonts_certs
    )

    注:确认你使用的是来自 android.support.v4.provider 包的FontRequest类。android.provider 包的和支持库不兼容。

    创建 FontRequest 时,你必须传入这些参数:

    • provider authority – 目前为止只能使用 Google 提供者 com.google.android.gms.fonts
    • provider package – 对于google 的字体提供者,包名是 com.google.android.gms
    • query - 你所请求的字体的查询字符串
    • 证书数组 – 用于校验提供者

    要请求一个新字体,需要使用 FontsContractCompat 的 requestFont() 方法。在 showFont() 最后一句加入:

    FontsContractCompat.requestFont(
        this,
        request,
        object : FontsContractCompat.FontRequestCallback() {
          override fun onTypefaceRetrieved(typeface: Typeface?) {
    
          }
    
          override fun onTypefaceRequestFailed(reason: Int) {
    
          }
        },
        handler
    )

    请求可下载字体是异步操作。 requestFont() 方法过一个 FontsContractCompat.FontRequestCallback 接口返回结果。如果请求成功, FontContractorCompat 会调用 onTypefaceRetreived() 方法。用传回的 Typeface 对象设置 View 的字体。启用所有按钮并隐藏进度指示器:

    override fun onTypefaceRetrieved(typeface: Typeface?) {
      buttons.forEach { button -> button.isEnabled = true }
    
      progressView.visibility = View.INVISIBLE
      fontTextView.typeface = typeface
    }

    如果请求错误,FontContractorCompat 会调用 onTypefaceRequestFailed()。通过向 showError() 传递一个错误代码来显示错误信息。

    override fun onTypefaceRequestFailed(reason: Int) {
      showError(reason)
    }

    请求字体时的最后一件东西是一个 Handler 实例。

    注:简而言之,处理程序使你可以将代码放到不同的线程执行。

    FentContractorCompat 用它来在于 Handler 关联的线程检索字体。确保您提供的 Handle 与UI线程无关。

    val handlerThread = HandlerThread("fonts")
    handlerThread.start()
    
    handler = Handler(handlerThread.looper)

    为了方便起见,创建一个私有字段,该属性负责保存这个 handler,通过这个属性初始化和检索 handler:

    private var handler: Handler? = null
    
    private val handlerThreadHandler: Handler
      get() {
        if (handler == null) {
          val handlerThread = HandlerThread("fonts")
          handlerThread.start()
          handler = Handler(handlerThread.looper)
        }
    
        return handler ?: throw AssertionError("Set to null by another thread")
      }

    第一次使用这个 handlerThreadHandler 属性时将初始化 handler 并返回它。

    现在 showFont() 最后一句变成这个样子:

    FontsContractCompat.requestFont(
        this,
        request,
        object : FontsContractCompat.FontRequestCallback() {
          override fun onTypefaceRetrieved(typeface: Typeface?) {
            buttons.forEach { button -> button.isEnabled = true }
    
            progressView.visibility = View.INVISIBLE
            fontTextView.typeface = typeface
          }
    
          override fun onTypefaceRequestFailed(reason: Int) {
            showError(reason)
          }
        },
        handlerThreadHandler
    )

    Build& run。开始答题:

    现在你会在每个问题上看到对应的字体!:]

    检索字体信息

    当你回答一个问题后,显示一个简单的问题所指字体的信息是一个不错的主意。因此,你的下一个任务是检索有关字族的信息。

    找到 QuestionActivity 的 loadFontFact() 方法。

    要获得字体信息,需要用 FontsContractCompact 的 fetchFonts() 方法。和之前一样,首先创建一个 FontRequest:

    val query = "name=$familyName"
    val request = FontRequest(
      "com.google.android.gms.fonts",
      "com.google.android.gms",
      query,
      R.array.com_google_android_gms_fonts_certs
    )

    然后传递给 fetchFonts() 方法。

    val result = FontsContractCompat.fetchFonts(this@QuestionActivity, null, request)

    如果指定名称有效,这将返回所请求字族的信息。您将在返回的对象的字体数组中查找它。你可以从返回对象中检索字体数组。

    注:不像 requestFont(),fetchFonts() 是同步的。它会在调用线程中执行并返回有效字体的信息。

    每个字体有以下属性:

    • uri – 字体提供者中该字体文件的 URI
    • ttcIndex – 如果提供一个 TTC_INDEX 文件,则指向该索引,否则返回 0
    • weight – 字重,整数值
    • italic – 如果字体风格为 italic,返回 true

    检查 result 的状态码,如果为 ok 则显示该字体的字重:

    if (result.statusCode == FontsContractCompat.FontFamilyResult.STATUS_OK) {
      with(textView) {
        text = getString(R.string.correct_answer_message, familyName, result.fonts[0].weight)
        visibility = View.VISIBLE
      }
    }

    字符串 R.string.correct_answer_message 已经有值了,并且它有一个代表字重的整型参数。

    获取字体数据是一个阻塞操作,应该在后台执行。使用 kotlin 的 doAsync 和 uiThread 块在后台线程上执行它:

    doAsync {
      val query = "name=$familyName"
      val request = FontRequest(
        "com.google.android.gms.fonts",
        "com.google.android.gms",
        query,
        R.array.com_google_android_gms_fonts_certs
      )
    
      val result = FontsContractCompat.fetchFonts(this@QuestionActivity, null, request)
    
      if (result.statusCode == FontsContractCompat.FontFamilyResult.STATUS_OK) {
        uiThread {
    
          with(textView) {
            text = getString(R.string.correct_answer_message, familyName, result.fonts[0].weight)
            visibility = View.VISIBLE
          }
        }
      } 
    }

    最后,进行错误处理并隐藏进度指示器。loadFontFact() 的最终代码如下:

    progressView.visibility = View.INVISIBLE
    
    doAsync {
      val query = "name=$familyName"
      val request = FontRequest(
          "com.google.android.gms.fonts",
          "com.google.android.gms",
          query,
          R.array.com_google_android_gms_fonts_certs
      )
    
      val result = FontsContractCompat.fetchFonts(this@QuestionActivity, null, request)
    
      if (result.statusCode == FontsContractCompat.FontFamilyResult.STATUS_OK) {
        uiThread {
          progressView.visibility = View.GONE
    
          with(textView) {
            text = getString(R.string.correct_answer_message, familyName, result.fonts[0].weight)
            visibility = View.VISIBLE
          }
        }
      } else {
        uiThread {
          showError(result.statusCode)
        }
      }
    }

    Build & run。回答一个问题,你会看到关于该字体的信息。

    XML 资源的可下载字体

    你还可以将可下载字体定义为 XML 资源。

    在 res\font 文件夹右键点击。选择 New\Font resource file。在对话框中,将文件名输入为 acme。

    为 元素添加字体相关属性:

    <?xml version="1.0" encoding="utf-8"?>
    <font-family xmlns:app="http://schemas.android.com/apk/res-auto"
      app:fontProviderAuthority="com.google.android.gms.fonts"
      app:fontProviderPackage="com.google.android.gms"
      app:fontProviderQuery="Acme"
      app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
    </font-family>

    这些内容不陌生。是你设置的这些属性是前面你传递给 requestFont() 的参数。只不过这次是放到 XML 中了。

    引用创建的字体资源,就像使用字族列和 .ttf 文件一样。打开res\activity_main.xml 布局文件,并将 acme 字体设置给 TextView tvFontQuiz:

    <android.support.v7.widget.AppCompatTextView
      android:id="@+id/tvFontQuiz"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/app_name"
      android:textColor="@android:color/black"
      android:textSize="@dimen/logo_text_size"
      android:textStyle="bold"
      app:fontFamily="@font/acme"
      app:layout_constraintRight_toRightOf="parent"
      app:layout_constraintLeft_toLeftOf="parent"               
      app:layout_constraintTop_toBottomOf="@+id/horizontalGuideline" />

    重复这个过程,添加 Bilbo Swash Caps 字体。

    打开 res/activity_main.xml,将 TextView tvTheGreat 的 font 属性设为 bilbo_swash_caps:

    <android.support.v7.widget.AppCompatTextView
      android:id="@+id/tvTheGreat"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/the_great"
      android:textColor="@color/colorAccent"
      android:textSize="@dimen/logo_text_size_small"
      app:fontFamily="@font/bilbo_swash_caps"
      app:layout_constraintBottom_toTopOf="@+id/horizontalGuideline"
      app:layout_constraintLeft_toLeftOf="parent"
      app:layout_constraintRight_toRightOf="parent" />

    Build & run:

    现在看到 FontQuiz 标签的字体了吗?第一次运行 app 时,你会注意字体在显示前有一个下载过程,因为它还没有下载并缓存。

    在 manifest 中提前声明字体

    还有一个意外之喜——你可以指定让 Android 在 App 启动前预加载的字体!为此,你必须在 manifest 中进行声明。

    点击 res\values 文件夹,按 ⌘N (或者 File\New) ,选择 Values resource file。

    在对话框中命名文件为 preloaded_fonts。

    在 resources 标签下添加字体数组,name 设为 preloaded_fonts:

    <array name="preloaded_fonts" translatable="false">
      <item>@font/acme</item>
      <item>@font/bilbo_swash_caps</item>
    </array>

    打开 manifests\AndroidManifest.xml 在 标签中添加 元素:

    <meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" />
    

    Build & run:

    呵!你的字体现在是预加载的了,只要应用程序一启动就可以使用。

    你创建了一个漂亮的 Font Quiz app——来玩一下吧!你能 5 题全对吗?:]

    接下来做什么

    这里是具有完整代码的最终项目

    选择你知道如何向 app 中添加自定义和可下载的字体了。

    google的官方文档是一个查找更多信息的好地方:font resourcesFonts in XMLDownloadable fonts

    如果你想看看 Google 字体提供者都有哪些字体,请看这里

    如果有任何问题或其他自定义和可下载字体的使用技巧,请在下面留言!

    展开全文
  • ‍在微软系统中默认只有...方法一:打开光驱,放入字体光盘,系统会自动运行安装字体程序,选中需要安装的字体,然后一路按NEXT就能把字体安装到WINDOWS的FONTS目录下。方法二:1、从网上下载喜欢的字体,尽量在正规网...
  • 《奈飞文化手册》这份PPT用了4种字体:微软...首先,我们需要下载字体下载字体前提是你知道这款字体的名称,然后用简单粗暴的方式,直接在百度里搜索相应的字体就会出现对应的下载链接。在这里,我们以禹卫书法行...
  • Android Oreo 可下载字体

    千次阅读 2017-09-16 09:47:06
    Android 8.0(API 级别 26)和 Android Support Library 26,现在允许 API 从一个字体供应程序里请求字体,而不需要绑定字体文件到 APK,或者由 APK 自行下载字体。该功能可通过 Android Support Library 26 运行在 ...
  • 字体图标的作用和使用方式

    千次阅读 2022-03-10 08:32:00
    记录:字体图标的作用和使用方式
  • 电脑怎么安装字体

    万次阅读 2021-07-23 03:30:12
    电脑安装字体的方法一复制字体文件到C:\WINDOWS\Fonts里到字体网站下载字体文件,一般下载下来的是zip或rar格式的压缩文件,解压后就得到字体文件,一般为.ttf格式。打开“我的电脑(计算机)”,在地址栏输入C:\...
  • icomoon图标字体下载与使用

    千次阅读 2020-10-29 15:55:05
    一旦字体加载了,图标就会马上渲染出来,不需要下载一个个图像。这样可以减少HTTP的请求数量,而且和HTML5的离线存储配合,可以对性能做出优化。 2、灵活性:不调字体可以像页面中的文字一样,通过font-size属性来对...
  • 隶书字体大全

    2021-06-16 09:49:37
    路由器之家网今天精心准备的是《隶书字体大全》,下面是详解!隶书字体怎么写隶书字体怎么写...隶书字体怎么写隶书点画的写法于篆书有明显的不同,篆书的点画可概括为点、直、弧3种,而发展到隶书已经具备了永字八法...
  • IconFont字体图标的下载与使用

    万次阅读 2020-05-01 12:26:50
    如何在Iconfont下载字体图标如何在IconFont-阿里巴巴矢量图标库下载字体图标IconFont1、首先打开官方网址2、登录相关账号3、添加需要的图标入库4、添加到项目5、新建项目6、下载到本地7、下期预告 如何在IconFont-...
  • linux安装字体方法

    千次阅读 2021-05-17 07:29:41
    1.查看系统中文字体#fc-list :lang=zh2.如果提示commont not fount 说明为安装fontconfig3.安装fontconfig#yum -y install fontconfig4.再次查看系统中文字体#fc-list :lang=zh5.确认是否存在字体 -->> simhei...
  • font字体

    2021-06-10 15:12:24
    路由器之家网今天精心准备的是《font字体》,下面是详解!html中的标签是什么意思HTML提供了文本样式标记,用来控制网页中文本的字体、字号和颜色,多种多样的文字效果可以使网页变得更加绚丽。其基本语法格式:文本...
  • 安装 1.官网下载安装包 ... (下载慢可能需要代理) ... 打开系统属性(win+R、输入sysdm.cpl),高级标签下环境变量,在系统变量内新建变量ACPath,值为刚才的安装路径。 4.安装PackageContro...
  • 如何Vue项目中加载字体的最佳做法

    千次阅读 2021-04-19 10:51:40
    添加字体不应该对性能产生负面影响。在本文中,我们将探讨在 Vue 应用程序中加载字体的最佳实践。 正确声明font-face的字体 确保正确声明字体是加载字体的重要方面。这是通过使用font-face属性来声明你选择的...
  • cad替换字体(cad找不到字体怎么替换)

    千次阅读 2021-01-26 16:36:29
    双击文字,出现文字编辑框,可以修改文字字体 还有一种方式是,把文字选中,然后看一下对应的文字样式,打开文字样式,将字体修改,但该样式下的所有文字都会一起.cad支持两种字体:一种是TrueType 字体,后缀名为...
  • 米开慕凉体字体

    2019-08-06 19:54:21
    米开慕凉体字体是一款非常漂亮的手写艺术字体,非常符合时下的书写方式,整体效果十分整齐优美,欢迎大家前来下载使用。 PS:该字体支持android、Windows、Mac等系统。 Windows系统文字安装方法 第一种:适合安装...
  • 1、首先在本公众号“资料大全”里面下载CAD万能字体包,然后把下载好的压缩包文件解压,并打开文件夹。如下图:2、再操作键盘的CTRL+A全选,然后对准任意一个文件,右键-点复制。如下图:3、对准电脑桌面CAD软件图标,...
  • 使用@font-face: 使用font-family: ...第二种安装方式打开控制面板,找到字体,把要的ttf文件拖进去就好 2. 把文件上的字体名称写进去就 运行效果(两种方式效果相同) ...
  • 字体换加插件,顾名思义,就是...下载字体换加插件下载介绍字体换加插件提供非常丰富的字体库,包括一些酷炫字体,你可以从中进行选择。同时,字体换加插件支持任何语言,基本可以改变每个网页的字体,不同的网页区...
  • 单独下载某个字体 你可以单独下载某个字体下载地址:https://github.com/powerline/fonts/tree/master/Meslo%20Slashed 下载好之后,双击 .ttf 文件直接在 MacOS 中安装即可。 然后打开 iTerm2,按 Command + , 键...
  • Windows操作系统的字体在哪个文件夹,如何添加字体文件字体在哪个...Windows中如何添加字体:第一步:通过百度搜索“字体下载”,找到合适的字体后,下载到本地计算机上;第二步:解压缩文件后,得到ttf、Fon、ttc...
  • 极速PDF编辑器是我们常用到一款PDF修改工具,你是否也遇到过系统提示缺少字体的情况,这种要怎么处理呢? 对于PDF的编辑器使用最多的就是文字的修改,但是选择文本工具后再点击文本却出现以下缺少字体的提示是怎么回...
  • 启用转为编程设计的连字字体,可以给你的变成带来不一样的体验。 本文内容连字字体连字字体推荐在编辑器中启用在 Visual Studio Code 中启用在 Visual Studio 或其他 Windows 系统自带软件中启用 连字字体 下面是 ...
  • :从下载字体,选择字体文件并单击鼠标右键,然后单击“安装”。 在Windows 10 1809或更高版本上,默认字体安装是按用户安装的,这可能会导致某些应用程序(主要是用Java编写)的兼容性问题。 为解决此问题,请右键...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 75,551
精华内容 30,220
关键字:

下载了的字体的打开方式