编写自定义控件构造函数的正确姿势 - defStyleAttr/defStyleRes
在学习自定义控件的时候,接触到第一样东西就是自定义控件的构造函数.这个东西可以说是很简单,但是如果你细细品味或许发现里面还有很多奥妙的地方.
这一篇博客就是深究到底如何正确编写自定义控件的构造函数.
默认的构造函数
习惯上,使用开发环境帮我们生成的是以下这四个构造函数
public class CustomView extends View {
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
但是一般我们会将它改写成一下这种形式
public class CustomView extends View {
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
但是你注意到在第二个构造函数里面我们给defStyleAttr传递0这样的做法是否正确呢?一种怎么样的姿势才是正确的呢?
当然我们这一篇博客就是为了解决这个问题而诞生的.
如何理解attr,declare-styleable
首先我们从最简单的开始,讲讲定义属性.
还是接着CustomView这个例子讲下去,我们首先给CustomView定义一些属性.
在attrs文件下新建declare-styleable节点,并且在该节点下添加attr节点.attr就是我们CustomView的属性了.
不使用declare-styleable节点,定义属性像customViewStyle属性那样可不可以?一开始我是拒绝这样的,但是我可以告诉你是可以的.这样做太麻烦了.declare-styleable节点会在背后帮你做很多工作.
看看declare-styleable节点的作用.其实我们通过观察customViewStyle属性和其他属性的区别就知道declare-styleable节点的作用了.
观察R文件,发现只要我们使用attr定义一个属性那么就会自动在R文件的attr类里生成一个用来标识该属性的int型属性(以该属性命名).
customViewStyle属性也一样是这样
当然我们需要找出他们的区别.看吧!如果使用declare-styleable节点包含attr属性.开发环境会帮我们自动生成一个数组并且把内容是所包含属性的标识,而且还生成了索引!
declare-styleable的作用就借此而已!当然你不喜欢可以不使用declare-styleable节点.
给一个属性赋值
给View的一个属性赋值一共有5中方式:
- 通过布局文件直接对属性赋值
- 通过给控件设置style属性,从而对某一些特点的属性赋值
- 通过自定义theme的方式,给某一属性赋值
- 通过自定义theme的方式,给某一个属性赋予一个style引用
编写View的时候通过defStyleAttr引用给属性设置默认值
以上这五种方式看起来头晕晕的,接下来通过代码的方式详细说明每一种方式.
首先给出自定义的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="attrA" format="string"></attr>
<attr name="attrB" format="string"></attr>
<attr name="attrC" format="string"></attr>
<attr name="attrD" format="string"></attr>
<attr name="attrE" format="string"></attr>
<attr name="attrF" format="string"></attr>
<attr name="attrG" format="string"></attr>
</declare-styleable>
<attr name="customViewStyle" format="reference">