自定义属性
实践
- 编写values/custom_attrs.xml,在其中编写styleable和item等标签元素
- 自定义一个CustomView(extends View)类
- 在布局文件中CustomView使用自定义的属性(注意namespace)
- 在CustomView的构造方法中通过TypedArray获取
custom_attrs.xml
1 | <?xml version="1.0" encoding="utf-8"?> |
<declare-styleable name="CustomAttrs">
这里的自定义属性的名称 name 如果不设置成和自定义 View的名字CustomView 一样的话,我们在xml布局文件里面将不会有这个属性的自动提示。所以这里最好是自定义属性的名称 和 自定义View一致。这该自定义View包含它的子类,在使用自定义属性时会有自动提示。
在布局文件中给 CustomView 配置自定义属性:
1 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
注意要在根布局中加入命名空间xmlns:custom,此处的 custom 名字可以随意指定。
在 CustomView 中获取自定义属性:
1 | public class CustomView extends View { |
测试打印结果:
1 | src = src , text = text , textSize = 48.0 |
format选项
- boolean:布尔值
- color:颜色值
- dimension:尺寸值
- enum:枚举值
- flag:位或运算
- float:浮点值
- fraction:百分数
- integer:整型值
- reference:参考某一资源ID
- string:字符串
flag与enum的差别:flag表示这几个值可以做或运算,你可以叠加使用,如用bold|italic表示既加粗也变成斜体,而enum只能让你选择其中一个值。
format即使用错,只要你自定义的View中获取对应类型值也是可以的,只是在布局中写代码时,IDE就不会根据你定义的format给出相应的提示了,所以最好在自定义View时还是仔细斟酌下类型。
AttributeSet与TypedArray
AttributeSet中保存的是该View声明的所有的属性,并且外面的确可以通过它去获取(自定义的)属性。但它和通过TypedArray获取到的有什么区别呢?
我们再添加下面的代码:
1 | int count = attrs.getAttributeCount(); |
测试打印结果:
1 | attrName = background , attrVal = #ffff0000 |
看到custom_bg这个属性的值 相信大家就明白了,如果某个属性我们用的是引用,那么通过AttributeSet获取的值只是这个资源的ID,而TypedArray获得的是解析过的ID的值。因此使用TypedArray是比较方便的。
在自定义Style中加入自定义attr
先在 values/styles.xml 中添加自定义 style:
1 | <style name="CustomStyle"> |
在布局文件中使用:
1 | <com.example.heqiang.testsomething.graphic.CustomView |
属性的获取和上面的是一样的。
1 | TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.CustomAttrs); |
结果:
1 | src = Hello , text = Hello world! , textSize = 30.0 |
在自定义Attr中加入自定义Style
我们在 custom_attrs.xml 新加下面的属性:
1 | <?xml version="1.0" encoding="utf-8"?> |
在布局文件中使用:
1 | <com.example.heqiang.testsomething.graphic.CustomView |
获取属性值:
1 | private void init(AttributeSet attrs,int defStyleAttr, int defStyleRes) { |
结果:
1 | customTheme=2131624100 |
获取Android原生属性值
参考上面代码中针对android:background属性的获取。