Android 批量使用iconfont

762 阅读2分钟

前言

iconfont是什么就不多说了,网上也有很多相关的教程。但是都是在正常使用中会有一些比较麻烦的事情。比如用svg去转成iconfont时需要维护一个String。如果是自己公司批量的svg第一步是要把它转成ttf文件,然后再根据使用端的不同维护一个String的key值。比如在Android中 <string name="add_line">\ue800</string>。一般如果真的用到这种转换大公司可能有相应的服务去转,但是自己怎么完成这个操作呢?

1、如何通过svg批量生成一个.ttf文件

使用flutter提供的网址fluttericon.com直接把本地的svg拖过去选中下载就好。这个好处是可以批量转成一个.ttf避免引入时资源多的问题

下载后会生成一个.dart文件和一个ttf。如果是使用flutter开发的话可以直接用.dart的文件。但是android就需要用脚本转了否则就要一个一个复制过去,很麻烦。

2、通过转换得到的.dart文件生成一个string.xml文件

class MyFlutterApp {
  MyFlutterApp._();

  static const _kFontFam = 'MyFlutterApp';
  static const _kFontPkg = null;

  static const IconData tab_right_plus_icon = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}

这个是刚刚转换得到的.dart文件。我们要转换成android中可以使用的string.xml

    <string name="tab_right_plus_icon">0xe800</string>
# coding=utf-8

import os
import re

MAP_ICON_NAME_TO_CHAR = {}

S_ICON_START = '<?xml version="1.0" encoding="utf-8"?>\n<resources>\n'
S_ICON_CONTENT = '    <string name="%s">\\u%s</string>\n'
S_ICON_END = '</resources>'
R_ICONFONT_DESC = '''
<!-- ########################此文件自动生成,禁止修改################################## -->
<!-- ######                  此文件自动生成,禁止修改                            ###### -->
<!-- ########################此文件自动生成,禁止修改################################## -->
\n'''

dartInfoPath = '../../assets/dart/info.dart' # .dart文件路径
outputFile = '../../res/value/string.xml'  # 输出文件路径
outputDir = '../../res/value/'


def main():
    """
        开始执行函数
    """

    # 读取.dart文件内容
    readDart()

   # 创建文件夹
    if not os.path.exists(outputDir):
        os.makedirs(outputDir)

    # 将内容写到输入目录
    writeOutputFile(outputFile)

def readDart():
    file = open(dartInfoPath, "r")

    for value in enumerate(file):
        c = re.compile(r' IconData (.*?) = IconData\((.*)')
        s = c.search(value[1])

        if s:
            MAP_ICON_NAME_TO_CHAR[s.group(1)] = s.group(2)[2:6]
            print('内容=='+  MAP_ICON_NAME_TO_CHAR[s.group(1)])

    file.close()
    return


def writeOutputFile(aOutputFile):
    """
        将从readInputFile解析的unicode 和 color 写入xml中
    """
    with open(aOutputFile, 'w') as f:
        f.writelines(S_ICON_START)
        f.writelines(R_ICONFONT_DESC)
        f.writelines('<!-- 根据svg文件名生成的iconfont对应的key -->\n')
        names = sorted(MAP_ICON_NAME_TO_CHAR.keys())
        for name in names:
            f.writelines(S_ICON_CONTENT % (name, MAP_ICON_NAME_TO_CHAR[name]))

        f.writelines('\n\n\n<!-- 根据svg文件内的颜色生成的iconfont对应的color(如果有的话) -->\n')

        f.writelines(S_ICON_END)


if __name__ == '__main__':
    main()

只是简单的把dart文件的内容转成了xml文件,很多语言都可以,不过python在github上很多这种现成的。运行后结果

    • 运行前需要先安装re模块pip3 install requests
    • 运行python ./iconfont_tool.py

在Android中使用

实际上iconfont就是一个文字,所以自定义一下字体就好。

class IconFontView : AppCompatTextView {
    private var mContext: Context

    constructor(context: Context) : super(context) {
        mContext = context
        initView()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        mContext = context
        initView()
    }

    private fun initView() {
        val iconfont = Typeface.createFromAsset(mContext.assets, "iconfont.ttf")
        typeface = iconfont
    }
}
    <com.demo.widget.IconFontView
        android:id="@+id/item_room_complain_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/add_line"
        android:textSize="24sp"
        android:layout_centerInParent="true"
        android:textColor="@color/mainColor"
        />