Fontawesome的使用(续)

[勘误]我在我的上篇博客一种可以代替图标的字符集Fontawesome一文中写到Fontawesome字体集在AS中是无法在布局编辑器中直接查看显示效果,这一结论是错误,今天工作中需求要求有一个字体图标会出现多次,如果采用博客中提到的方式处理,会重复定义许多id,代码重复,因此寻思通过自定义属性为TextView设置typeface,这样可以直接在布局中就可以实现使用fontawesome,岂不快哉!


看右边的小箭头

看需求,是要在所有的条目右边加上一个“右箭头”的字体图标,很显然这些字体图标对应同一个unicode值,沿用之前的方法会造成大量重复代码,所以我想如果可以直接在布局上设置TextView的typeface不是很便捷嘛,撸起袖子加油干~


一、为TextView自定义属性 mytypeface

自定义属性在平时的开发中,还是属于比较常见的需求,这个项目中我是想为TextView设置一个自定义属性mytypeface来在布局中直接指定typeface,从而避免在代码中一个个控件的findViewById设置。刚好复习下自定义控件的具体实现:
1. 自定义属性定义在什么地方
通常来说,自定义属性声明和定义在values/attrs.xml中,如果没有请创建即可,在attrs.xml中有2个重要的节点:declare-styleable/attr ,其中declare-styleable意思是指宣布/定义的意思,需要指出的是其name属性值就是attr属性的集合名称可以随便起,不一定要是我们的自定义控件的名称,而接下来的节点attr自然就是具体的属性名称,如mytypeface.

  • 我的自定义属性的声明文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="MyIconTextView">
        <attr name="mytypeface" format="string"/>
    </declare-styleable>

</resources>

这里,要提一句,attr节点的format属性不是必须的,我这里为什么要定义mytypefacestring类型?这个就要看TextView的源码啦,因为我是想通过在布局中为TextView设置属性自动完成让TextView使用Fontawesome字体,那么我就必须要知道TextView是如何为其设置typeface的。
我们知道:系统的控件属性都是定义在路径sdk\platforms\android-23\data\res\values\attrs.xml中的


typeface在系统attrs.xml中定义

可以看见,在系统属性中,使用enum枚举类型将typeface定义为四个值,分别是normal/sans/serif/monospace。追踪TextView的源码发现如下蛛丝马迹:

是不是设置上typeface啦

具体调用处

看最终调用处,是不是可以把在xml设置的typeface的enum值取出来并进行分支判断从而应用,因此我想其实可以直接自定义属性来避免重复在代码中为TextView设置使用Fontawesome字体。看到这里,你应该知道我为什么要把typeface定义成 string类型,还得猜到我要设置什么样的字符串?纳尼,还没看懂~好吧继续向下看,吼~吼~

2. 自定义属性什么时候使用到(AttributeSet与TypedArray的区别)
在上面其实,我已经分析了,我们在xml中定义的属性是何时被解析出来并使用的,那就是在TextView的构造中:

View构造的特点看出来没,最终调用的是参数最多的构造

最终调用的是参数最多的构造,在构造的参数中有1个参数需要重点解释下:

  • 参数:AttributeSet
    顾名思义就是指所有被系统或自定义的属性的set集合(当然,实际包含的内容以我们在布局中使用到相关属性),很显然这里面有我们关心的属性,这里是取出属性name及其value的一个方法,但是缺点是如果xml的属性的value不是值而是一个资源引用id,那么取出具体值势必需要进一步解析id,比较麻烦,因此有了TypedArray
    更细节的内容,建议参考Android 深入理解Android中的自定义属性

3.自定义属性使用需要注意什么问题

  • 使用自定义属性需要注意的是使用namespace,即命名空间,一般可以xmlns:你的命名空间名称,如我的就是xmlns:wx=”http://schemas.android.com/apk/res-auto”
二、自定义MyIconTextView

已经确定好自定义属性,要想使用自定义属性,就必须进行自定义控件,在构造中获取自定义属性并应用到控件上,因为本文基于TextView控件,因此自定义MyIconTextView extends TextView,代码如下:

public class MyIconTextView extends TextView {
    public MyIconTextView(Context context) {
        this(context, null);
    }

    public MyIconTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyIconTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyIconTextView);
        String typeface = typedArray.getString(R.styleable.MyIconTextView_mytypeface);
        setTypeface(FontManager.getTypeface(context, typeface), 0);//使用FontManager核心类
        typedArray.recycle();  //注意回收
    }

    @Override
    public void setTypeface(Typeface tf, int style) {
        super.setTypeface(tf, style);
    }
}

这里需要指出的是,如何访问到我们定义在attrs.xml中的自定义属性呢?答案是,通过类TypedArray 实现的,R.styleable.MyIconTextView中所有的attrR.java中都有映射,要想访问到declare-styleable的子标签attr必须通过R.java实现,因为所有的attrR.java中以declare-styleable’s name_attr’s name生成了对应的常量,aapt干的。

三、在布局xml中MyIconTextView应用自定义属性mytypeface

以上工作都做完后,就可以自由在布局xml中使用自定义的MyIconTextView并直接引用属性mytypeface,看看下面的布局文件,博主没想到这么做后,布局编辑器竟然可以实时看出字体绘制后显示的图标效果,搜嘎,so good……

<com.zbiti.yuntu.view.MyIconTextView
            android:layout_width="18dp"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:gravity="center"
            android:text="@string/fa_angle_right"
            android:textSize="16sp"
            wx:mytypeface="fonts/fontawesome-webfont.ttf" />

布局编辑器看来,在写xml时,就已经调用了构造对控件进行了渲染显示啦


布局编辑器渲染

oh~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值