该文章我们以自定义View继承TextView为例来讲解
创建自定义View命名MyTextView,并使其继承TextView
1、自定义View时第一个构造函数
// 第一个构造函数主要是在Java代码中声明一个MyTextView时所用 // 类似这种(MyTextView myTextView=new MyTextView(this);) // 不过如果只用第一个构造函数,声明的View并没有任何的参数,基本是个空的View对象
2、自定义View时第二个构造函数
//在XML布局文件中引用时,系统初始化该View时,调用的是第二个构造函数 //参数attrs是我们在xml中配置的参数
前两个构造函数介绍完了,我们说下后两个构造函数
系统默认只会调用前两个构造函数,至于后两个构造函数的调用,通常是我们自己在构造函数中主动调用的,TextView源码亦是如此:
View类的后两个构造函数都是与主题相关的,也就是说,在你自定义View时,如果不需要你的View随着主题变化而变化,有前两个构造函数就OK了,但是如果你想你的View随着主题变化而变化,就需要利用后两个构造函数了。
比如我们定义主题时,用两种方式给自定义View设置主题颜色,如下设置:
xml布局展示:
在主题设置中颜色有两个赋值,为什么最终显示出来的颜色是绿色,而非紫色呢?????
这就涉及到第三个构造函数了,例如源码中TextView,第三个构造函数的调用:
3、自定义View时第三个构造函数
不会自动调用,一般是在第二个构造函数里主动调用
3.1、第三个构造函数中的参数:defStyleAttr 是属性资源, 既然是属性资源,我们首先需要自定义属性
3.2、在主题中对这个自定义属性赋值。(红色)
3.3、构造函数中使用这个自定义属性
4、自定义View时第四个构造函数
不会自动调用,一般是在第三个构造函数里主动调用
第四个构造函数中,defStyleRes这个参数不再是Attr了,而是真正的style。
4.1、定义一个真正的style(橙色)
4.2、在主题未声明属性值时,我们调用第四个构造函数,第四个参数赋值这个橙色style,以这种方式定义出的View,其主题就是这个定义的defStyleRes(想要最终结果显示橙色的前提是:只有在第三个参数defStyleAttr为0,或者主题中没有找到这个defStyleAttr属性的赋值时,才会启用)
由此也可见3种方式设置 textColor的优先级:
defStyleAttr(红色) > defStyleRes(橙色) > theme 中直接定义(绿色)
//注解的意思是告诉Lint工具不需要对这个类进行 AppCompat 兼容性的检查
@SuppressLint("AppCompatCustomView")
public class MyTextView extends TextView {
private final String TAG= MyTextView.class.getSimpleName();
public MyTextView(Context context) {
super(context);
Log.d(TAG, "MyTextView: first ");
}
public MyTextView(Context context, @Nullable AttributeSet attrs) {
//super指父类的
//super(context, attrs);
//this指当前对象,在这里是调用当前对象的第三个构造函数
//this(context, attrs, R.attr.textViewColorStyle);
this(context, attrs,0);
Log.d(TAG, "MyTextView: second ");
}
public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
// super(context, attrs, defStyleAttr);
//调用当前对象的第四个构造函数
this(context, attrs,defStyleAttr, R.style.OrangeTextStyle);
Log.d(TAG, "MyTextView: three ");
}
public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
Log.d(TAG, "MyTextView: four ");
}
}