问题
I'm learning about using Custom Views from the following:
http://developer.android.com/guide/topics/ui/custom-components.html#modifying
The description says:
Class Initialization As always, the super is called first. Furthermore, this is not a default constructor, but a parameterized one. The EditText is created with these parameters when it is inflated from an XML layout file, thus, our constructor needs to both take them and pass them to the superclass constructor as well.
Is there a better description? I've been trying to figure out what the constructor(s) should look like and I've come up with 4 possible choices (see example at end of post). I'm not sure what these 4 choices do (or don't do), why I should implement them, or what the parameters mean. Is there a description of these?
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);
}
回答1:
You don't need the first one, as that just won't work.
The third one will mean your custom View
will be usable from XML layout files. If you don't care about that, you don't need it.
The fourth one is just wrong, AFAIK. There is no View
constructor that take a Map
as the third parameter. There is one that takes an int
as the third parameter, used to override the default style for the widget.
I tend to use the this()
syntax to combine these:
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
}
You can see the rest of this code in this book example.
回答2:
Here's a my pattern (creating a custom ViewGoup
here, but still):
// 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
}
}
and
// view_custom.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Views -->
</merge>
回答3:
When you are adding your custom View
from xml
like :
<com.mypack.MyView
...
/>
you will need the public constructor MyView(Context context, AttributeSet attrs),
otherwise you will get an Exception
when Android
tries to inflate
your View
.
And when you add your View
from xml
and also specify the android:style
attribute
like :
<com.mypack.MyView
style="@styles/MyCustomStyle"
...
/>
you will also need the third public constructor MyView(Context context, AttributeSet attrs,int defStyle)
.
The third constructor is usually used when you extend a style and customize it, and then you would like to set that style
to a given View
in your layouts
Edit Details
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);
}
See this
来源:https://stackoverflow.com/questions/2884501/android-custom-view-constructor