【Android XML】Android XML 转 Java Code 系列之 Selector(2)

今天我们要把drawable下的selector的XML文件转换成Java代码。(打包进jar,不依赖apk)

在转换工具中的代码为:

https://github.com/SickWorm/AndroidXMLToJava/blob/master/src/com/excelsecu/androidx2j/SelectorTranslator.java

 

Selector是什么?就是给Button等控件使用的一个根据状态改变控件颜色或背景的状态器,它一般放在drawable目录下。

Selector分两种,一种是指定color和alpha的状态器,XML形式如下:

另一种是指定drawable的状态器,XML形式如下:

 

知道了XML格式,我们如何去找到对应实现的类呢?这时候就应该上万能的http://developer.android.com/(科学上网,我用红杏我自豪)寻找selector。点击第一个链接:

http://developer.android.com/guide/topics/resources/color-list-resource.html

在这个文档上我们可以明显看到第一个XML对应的类就是ColorStateList(里面介绍的第一个就是)。而第二个XML,我一开始找了很久都没找到,直到我点开文档最下方的State List Drawable,发现赫然写着:

StateListDrawable(原谅我激动的心情)

点进这个类看到对应的XML布局,确定这就是第二个XML布局啦。

 

找到了对应的类,接下来要开始正式的工作了。我们先从ColorStateList下手。

所谓转换,其实就是构造一个对应类的对象,然后把XML的属性对应的内容用Java代码的方式“填充”进这个对象中便完成了。在使用到这个XML的地方,也用对应的设置方法把该成员设置进去就可以了。

那首先找到ColorStateL的构造函数:ColorStateList(int[][] states, int[] colors);

一开始便难倒我了。。这诡异的两个int数组是shenmegui?看看人家控件家族(Button, TextView等等)只需要一个context就可以构造了。根据名字猜测,这两个数组估计是对应的各种状态和颜色。那我们接下去认证这个猜想。

说时迟那时快,我发现了另一个函数:createFromXml(Resources r, XmlPullParser parser);

该函数就是给我们用Java代码动态解析XML用的方法。里面肯定有对XML各参数解析的过程,赶紧看一下源代码(作为一个开源操作系统的程序猿,一定要下一份源码)。

我们跟着这个XmlPullparser走,因为他里面藏着XML信息。结果发现他调用了createFromXmlInner。继续跟,发现调用了colorStateList.inflate。看inflate就知道是解析函数啦!那我们来详细分析这个inflate:

(下面是我分析inflate函数时的笔记,应该算比较详细了)

我们现在来看下ColorStateList的构造函数:

inflate得到的两个最终产物 mStateSpecs 和 mColors 就是我们想要的构造函数!我们只要照葫芦画瓢,照inflate画数组,就可以把这两个数组写出来了。ColorStateList被降服了!

喔,忘了还有一个遗留问题:

穿山甲到底说了什么?

stateResId到底是什么?

再看分析:

这里“com.android.internal.R,使用的时候是android.R”,说服力可能不足,但这个表http://developer.android.com/reference/android/R.attr.html应该是可靠的,Google不会做两个表出来吧。。

 

接下来还有一个

StateListDrawable(怎么还是这么大)

这个东西就简单的多了,构造器不需要参数,直接new StateListDrawable()即可。添加状态使用addState(int[] stateSet, Drawable drawable)。stateSet和ColorStateList的规则是一样的,drawable就是XML文件里面指定的drawable资源。这里就不多赘述了。

 

注意:

虽然ColorStateList对应的selector XML放在drawable文件夹里面,但他本身是一个自定义类!父类是Object!和

StateListDrawable(啊啊啊啊吓死我了)

不一样,这货父类是Drawable,可以用getDrawable()获取。如果你用getDrawable(R.drawable.colorStateList)获取对应资源的话是会崩溃的。为什么要提到这点呢?因为转换工具(详细介绍看第一篇文章)有一个仿照getResources()专门管理资源的类(叫AXMLResources),因为这个ColorStateList的特殊原因,就要另外用函数处理了。

 

版权所有,转载请注明出处:

http://sickworm.com/?p=34 




没有评论


你先离开吧:)



发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据