安卓系统为我们提供了丰富的控件,但是在实际项目中我们仍然需要重新通过布局来实现一些效果,比如我们需要一个上面图标,下面文字的button,类似于下面这样的:
最直接的解决办法是通过将imageview和textview放在一个垂直排列的LinearLayout中,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
但是每一个button都需要这么长的代码,上面三个按钮的话就需要重复写三次,而且别人一看是个LinearLayout,不会将它button联系起来。
如果有一种办法能将上面那个布局组合成一个控件就好了。
的确是有办法的。主要有两方面的工作。
1.新建一个继承自LinearLayout的类(也可以是其他布局类,不过LinearLayout好像比较合适),然后通过inflater在这个类的构造函数中将上面的布局添加进去。
2.为了能在xml中也给这个自定义控件赋予属性来获得现实效果,比如字体大小、图标资源等,我们还需要在attrs文件中申明一些自定义属性。你可以查阅declare-styleable了解这是怎么回事。
我这里有一个已经实现了这种button效果的类FlexImageButton:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|
在attrs.xml文件中我们声明一些自定义属性,这里我们希望我的FlexImageButton能拥有可以灵活设置的文字属性,字体大小属性、图标资源属性,因此我这样定义:
1 2 3 4 5 6 7 |
|
其中format=
"reference"
表示这个属性的值类型是资源id,也就是说在使用FlexImageButton的时候我只可以用资源id来为这个属性赋值。属性值类型有那些,我在文章结尾的附录里面一一列出。
上面我们已经完成了一个自定义的控件,activity的布局文件中如下使用FlexImageButton:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
仔细的人会注意到所有这些属性中,有两种形式。其中凡是android:开头的都是系统属性,而
1 2 |
|
为我自定义的属性,为什么是cl:开头?
你也可以不用cl开头,但是不管你用什么开头,如果你用到了自定义属性,你都必须在activity布局文件的最开始这样声明:
1 2 3 4 |
|
其中cl
就是刚刚用到的,com.jcodecraeer.client
为我的apk包名,注意是apk包名,而不是你自定义控件的在包中的路径。
附录:自定义属性的值类型:
1. reference:参考某一资源ID。
(1)属性定义:
1 2 3 |
|
(2)属性使用:
1 2 3 4 |
|
2. color:颜色值。
(1)属性定义:
1 2 3 |
|
(2)属性使用:
1 2 3 4 |
|
3. boolean:布尔值。
(1)属性定义:
1 2 3 |
|
(2)属性使用:
1 2 3 4 |
|
4. dimension:尺寸值。
(1)属性定义:
1 2 3 |
|
(2)属性使用:
1 2 3 |
|
5. float:浮点值。
(1)属性定义:
1 2 3 4 |
|
(2)属性使用:
1 2 3 |
|
6. integer:整型值。
(1)属性定义:
1 2 3 4 |
|
(2)属性使用:
1 2 3 4 |
|
7. string:字符串。
(1)属性定义:
1 2 3 |
|
(2)属性使用:
1 2 3 4 |
|
8. fraction:百分数。
(1)属性定义:
1 2 3 4 |
|
(2)属性使用:
1 2 3 4 |
|
9. enum:枚举值。
(1)属性定义:
1 2 3 4 5 6 |
|
(2)属性使用:
1 2 3 |
|
10. flag:位或运算。
(1)属性定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
(2)属性使用:
1 2 3 |
|
注意:属性定义时可以指定多种类型值:
(1)属性定义:
1 2 3 |
|
(2)属性使用:
1 2 3 4 |
|