Android 字体使用踩坑指南

Android 字体使用踩坑指南

最近项目改版,根据ui的设计,需要使用到三字体。在使用过程中遇到一些坑,于是有了这个避坑指南!

字体压缩

第一个坑!字体库的体积太大。
字体压缩的前提是要使用的内容是可控的,换句话说,使用字体的文本时一些固定的内容,比如说金额,姓氏,颜色之类的!压缩的原理是只提取要显示的文本内容,然后打包成字体包!这里我用到的是一个工具包,附上现在链接下载链接。具体的使用步骤见上面链接,可以有效的减少字体库的体积!

使用字体库方法一

  • 准备好的要用的字体放在如下目录


    放置目录
  • 加载字体库

TextView textView= (TextView) findViewById(R.id.text_view); 
Typeface typeface=Typeface.createFromAsset(getAssets(),"fonts/orange.ttf"); 
textView.setTypeface(typeface);

第二个坑,assets 目录加载不到!
这是最常见的用法,但是由于某些特殊的原因,assets 目录加载不到,那就用到另外一种方式

使用字体库方法二

  • 放置字体库
    在 res 目录下新建一个 font 的目录


    放置目录二

然后将字体库文件放进新建的font 文件下。

  • 加载字体库
    TextView textView = (TextView) findViewById(R.id.text_view);
    Typeface typeface = ResourcesCompat.getFont(this, R.font.orange);
    textView.setTypeface(typeface);

第三个坑,v4包的版本太低,切不能升级!
这种方式也又一个缺陷,就是 ResourcesCompat.getFont 这个函数是在android-support-v4这个包的版本是26+,才可以使用!这个就是遇到的第二个坑!这两种方式的都失败了,于是采用第三种方法!

使用字体库方法三

由于前两种方法都失败了,所以有了这种方法!办法总比空难多。先说原理查看 Typeface 这个类有一个函数

 /**
     * Create a new typeface from the specified font file.
     *
     * @param path The full path to the font data.
     * @return The new typeface.
     */
    public static Typeface createFromFile(String path) {
        if (sFallbackFonts != null) {
            FontFamily fontFamily = new FontFamily();
            if (fontFamily.addFont(path, 0 /* ttcIndex */)) {
                FontFamily[] families = { fontFamily };
                return createFromFamiliesWithDefault(families);
            }
        }
        throw new RuntimeException("Font not found " + path);
    }

这个函数允许从一个文件路径加载字体库,于是采用这种方法!我们在res目录下新建一个 raw目录,然后把字体文件放进去!我们需要被这个文件写入手机的内存中,然后从内存再加载这个文件!写入文件的路径选择这个 /data/data/packagename/files/目录下,目的就是为了避开权限sdcard 的读写权限检查!

  • 写入文件
private Typeface copyTextTypeToFile() {

        File filesDir = mContext.getFilesDir();
        File puhuitiMiniPath = new File(filesDir, "orange.ttf");
                //判断该文件存不存在
        if (!puhuitiMiniPath.exists()) {
                //如果不存在,开始写入文件
            copyFilesFromRaw(mContext, R.raw.orange, "orange.ttf", mContext.getFilesDir().getAbsolutePath());
        }
        return Typeface.createFromFile(puhuitiMiniPath);
    }


        ...

 void copyFilesFromRaw(Context context, int id, String fileName,String storagePath){
        InputStream inputStream=context.getResources().openRawResource(id);
        File file = new File(storagePath);
        //如果文件夹不存在,则创建新的文件夹
        if (!file.exists()) {
            file.mkdirs();
        }


        String storagePath = storagePath + SEPARATOR + fileName;
     
         File file = new File(storagePath);
        try {
            if (!file.exists()) {
                // 1.建立通道对象
                FileOutputStream fos = new FileOutputStream(file);
                // 2.定义存储空间
                byte[] buffer = new byte[inputStream.available()];
                // 3.开始读文件
                int lenght = 0;
                while ((lenght = inputStream.read(buffer)) != -1) {// 循环从输入流读取buffer字节
                    // 将Buffer中的数据写到outputStream对象中
                    fos.write(buffer, 0, lenght);
                }
                fos.flush();// 刷新缓冲区
                // 4.关闭流
                fos.close();
                inputStream.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

将文件写入之后加载

textView.setTypeface(typeface)

这里只是说明一下主要的实现思路,具体实现需要结合实际的场景!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,174评论 1 32
  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,499评论 0 9
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,955评论 0 5
  • WinRAR - 最新版本的更新 版本 5.50 1. WinRAR 和命令行 RAR 默认使用 RAR ...
    王舒璇阅读 2,435评论 0 2
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,926评论 0 10