Android自定义视图构造函数

我正在学习如何使用自定义视图:

http://developer.android.com/guide/topics/ui/custom-components.html#modifying

描述说:

类初始化一如既往,超级被称为第一。 而且,这不是一个默认的构造函数,而是一个参数化的构造函数。 当EditText从一个XML布局文件中被膨胀时,这些参数被创build,因此,我们的构造函数也需要把它们传递给超类的构造函数。

有更好的描述吗? 我一直在试图弄清楚构造函数应该是什么样子,而且我已经提出了4种可能的select(请参阅文章末尾的示例)。 我不确定这四个select做了什么(或不这样做),为什么我要实现它们,或者参数是什么意思。 有没有这些描述?

public MyCustomView() { super(); } public MyCustomView(Context context) { super(context); } public MyCustomView(Context context, AttributeSet attrs) { super(context, attrs); } public MyCustomView(Context context, AttributeSet attrs, Map params) { super(context, attrs, params); } 

你不需要第一个,因为这是行不通的。

第三个意味着你的自定义View将可用于XML布局文件。 如果你不在乎,你不需要它。

第四个是错的,AFAIK。 没有View构造函数将Map作为第三个参数。 有一个接受int作为第三个参数,用来覆盖widget的默认样式。

我倾向于使用this()语法来组合这些:

 public ColorMixer(Context context) { this(context, null); } public ColorMixer(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ColorMixer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // real work here } 

你可以在本书的例子中看到这段代码的其余部分。

这是我的模式(在这里创build一个自定义ViewGoup ,但仍然):

 // CustomView.java public class CustomView extends LinearLayout { public CustomView(Context context) { super(context); init(context); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public CustomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context ctx) { LayoutInflater.from(ctx).inflate(R.layout.view_custom, this, true); // extra init } } 

 // view_custom.xml <merge xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Views --> </merge> 

当你从xml添加自定义View ,如:

  <com.mypack.MyView ... /> 

您将需要公共构造函数 MyView(Context context, AttributeSet attrs),否则当Android尝试inflate ViewMyView(Context context, AttributeSet attrs),您将得到一个Exception

而当你添加从xmlView ,并指定 android:style attribute如:

  <com.mypack.MyView style="@styles/MyCustomStyle" ... /> 

你还需要第三个公共构造函数 MyView(Context context, AttributeSet attrs,int defStyle)

第三个构造函数通常用于扩展样式和自定义样式,然后您想将style设置为布局中给定的View

编辑详情

 public MyView(Context context, AttributeSet attrs) { //Called by Android if <com.mypack.MyView/> is in layout xml file without style attribute. //So we need to call MyView(Context context, AttributeSet attrs, int defStyle) // with R.attr.customViewStyle. Thus R.attr.customViewStyle is default style for MyView. this(context, attrs, R.attr.customViewStyle); } 

看到这个