现在发现又两种方式:
第一种:每个构造函数分别调用基类的构造函数,再调用一个公共的初始化方法做额外初始化。
public class MyView extends ListView {
public MyView(Context context) {
super(context);
sharedConstructor();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
sharedConstructor();
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
sharedConstructor();
}
private void sharedConstructor() {
// Do some initialize work.
}
}
第二种:
级联式调用,每一个构造函数调用比它多一个参数的构造函数,最后一个构造函数调用基类的构造函数,最后在做一些额外的初始化工作。
public class MyView extends ListView {
public MyView(Context context) {
this(context, null);
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// Other initialize work.
}
}
答案是:第一种
结论是:最好使用第一种,因为第二种方法在某些情况下会有问题,比如你自定义的View继承自ListView或者TextView的时候,ListView或者TextView内部的构造函数会有一个默认的defStyle, 第二种方法调用时defStyle会传入0,这将覆盖基类中默认的defStyle,进而导致一系列问题。以ListView为例,看看它的构造函数。
public ListView(Context context) {
this(context, null);
}
public ListView(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.listViewStyle);
}
public ListView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public ListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
// Other works.
}