版权声明:本文为博主原创文章,未经博主允许不得转载。
转载请注明出处:
http://blog.csdn.net/qq347198688/article/details/52665975
本文出自【何嘉龙的博客】
1. 引言
对于自定义属性,我相信大家都接触过,使用过。但是可能对自定义属性存有一些疑问,比如说:
-
为什么要用到自定义属性?
-
为什么在xml文件中要用到自定义的命名空间?
-
TintTypedArray与TypedArray有什么不同?
-
format有什么用?可以不加么?
让我们带着这些问题,来进行这篇博客的学习。
2. 常见的例子
进行学习的最好方式,就是有例子作为参考,而不是只是单纯给你灌输理论知识,这样只会苦涩难懂,让新手畏惧不前。
- 在value目录下新建一个attrs.xml文件如下:
- 接着在attrs.xml文件中,写入自定义声明的属性:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 自定义一个View类
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 在布局文件中使用
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
好了,我们的自定义属性写好了,而且还放在自定义布局中使用了,那这次应该可以看到结果了吧。让我们来运行一下:
咦?好像报错了。让我们来看一下这个错误是什么?
大概意思就是, 加载我们的这个自定义View出错。我找了很久才找出解决方法,解决方法就是在自定义View里面加入这几行代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
至于出错的原因呢?我推断是当我们在自定义布局中写入我们的自定义View时,所用到的构造函数是带有两个参数的。所以,大家为了防止以后出现莫名其妙而又很难找的错误,最好把那几个构造方法都写出来。
好了,我们把错误已经找出来了,那让我们再继续运行一下:
控制台已经帮我们把结果打印出来了。再让我们看一下,那个小程序有没有把那些结果显示出来:
嗯?怎么什么都没有?哈哈,其实这才是正常的,因为你根本都没有在自定义View里面去调用onMesure(),onDraw方法,具体的请参考我转载的自定义View文章系列。咦?我们好像没有定义test_text、test_testAttr这两个item吧?但是又好像很眼熟。
其实,正如你们脑海里想的那样,代码中自定义属性名称就是这样的,”_”前面的是数组名test,后面是自定义属性名。至于declare-styleable 在Android自定义属性详细剖析(二)中剖析。
3. 解决疑问
在通过一个示例之后,再来跟大家一起解决前面提出的问题。
- 自定义属性的基本流程
我们现在attrs.xml文件中声明我们所需要的自定义属性,然后在布局文件中通过命名空间找到我们的自定义属性,接着再在布局文件中使用,然后Java代码中通过obtainStyledAttributes()方法将布局文件中的自定义属性的值给传进来,进行后续操作。基本流程就是这样了。
- 为什么要使用自定义属性?
自定义属性,可以让我们直接在布局文件中,使用自己定义的属性,来完成需求。使用过开源框架的同学们应该都知道,我们在使用开源框架时,在布局文件中一般都要加上自己的自定义属性,因为这些属性系统没给我们,是我们自己定义的,来完成很多需求的。可能有同学就有疑问了,那为什么我们不直接在代码中完成需求呢?这个问题很好,其实这体现了面向对象的特性——封装性,你要用一个开源框架时,你都不需要去了解代码内部的结构,只需要在自定义布局中加入自定义属性,不是很简单么?
- 为什么在xml文件中要用到自定义的命名空间?
先让我们来看到自定义命名空间的格式,xmlns:app=”http://schemas.Android.com/apk/res-auto”或者xmlns:app=”http://schemas.android.com/apk/res/com.example.attrtest”,这两个其实是一样的,但是我推荐使用第一个,IDE会自动帮你寻找到项目中的所有自定义属性。所以,要用到自定义的命名空间就是为了帮你去找你自定义的属性。
- TintTypedArray与TypedArray有什么不同?
可以看到,官方的解释是,TintTypedArray跟TypedArray提供一样的API,所以这两个随便使用哪一个都一样,不需要纠结。
- format有什么用?可以不加么?
这个是不加后的结果,直接报错。所以format是必须要加的。如果类型都不知道,我们怎么指定自定义属性的值。
format可以理解为类型, fomat的属性自己定义 根据自己的需要来选择string , integer , dimension , reference , color , enum……reference:参考指定Theme中资源ID。
dimension:尺寸值
float:浮点型
boolean:布尔值
integer:整型
string:字符串
fraction:百分数
flag:位或运算
Color:颜色
enum:枚举
好啦,自定义属性的第一部分算是讲解完了,如果感兴趣的同学,可以接着看Android自定义属性详细剖析(二)。