在开发android开发过程中,很多人都会遇到自定义view,一般都需要继承自View类,而当你打开View类的源码时,发现会有四个构造函数,那么这四个构造函数是如何使用的呢,怎么合理的利用四个构造函数呢,本文将进行一定探究,希望能够抛砖引玉。
[实验结果]
一 View类的四个构造函数
先从android源码中把四个构造函数拉出来看看。。
1 第一个构造函数
/**
* Simple constructor to use when creating a view from code.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
*/
public View(Context context)
2 第二个构造函数
/**
* Constructor that is called when inflating a view from XML. This is called
* when a view is being constructed from an XML file, supplying attributes
* that were specified in the XML file. This version uses a default style of
* 0, so the only attribute values applied are those in the Context's Theme
* and the given AttributeSet.
*
* <p>
* The method onFinishInflate() will be called after all children have been
* added.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param attrs The attributes of the XML tag that is inflating the view.
* @see #View(Context, AttributeSet, int)
*/
public View(Context context, @Nullable AttributeSet attrs)
3 第三个构造函数
/**
* Perform inflation from XML and apply a class-specific base style from a
* theme attribute. This constructor of View allows subclasses to use their
* own base style when they are inflating. For example, a Button class's
* constructor would call this version of the super class constructor and
* supply <code>R.attr.buttonStyle</code> for <var>defStyleAttr</var>; this
* allows the theme's button style to modify all of the base view attributes
* (in particular its background) as well as the Button class's attributes.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param attrs The attributes of the XML tag that is inflating the view.
* @param defStyleAttr An attribute in the current theme that contains a
* reference to a style resource that supplies default values for
* the view. Can be 0 to not look for defaults.
* @see #View(Context, AttributeSet)
*/
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
4 第4个构造函数
/**
* Perform inflation from XML and apply a class-specific base style from a
* theme attribute or style resource. This constructor of View allows
* subclasses to use their own base style when they are inflating.
* <p>
* When determining the final value of a particular attribute, there are
* four inputs that come into play:
* <ol>
* <li>Any attribute values in the given AttributeSet.
* <li>The style resource specified in the AttributeSet (named "style").
* <li>The default style specified by <var>defStyleAttr</var>.
* <li>The default style specified by <var>defStyleRes</var>.
* <li>The base values in this theme.
* </ol>
* <p>
* Each of these inputs is considered in-order, with the first listed taking
* precedence over the following ones. In other words, if in the
* AttributeSet you have supplied <code><Button * textColor="#ff000000"></code>
* , then the button's text will <em>always</em> be black, regardless of
* what is specified in any of the styles.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param attrs The attributes of the XML tag that is inflating the view.
* @param defStyleAttr An attribute in the current theme that contains a
* reference to a style resource that supplies default values for
* the view. Can be 0 to not look for defaults.
* @param defStyleRes A resource identifier of a style resource that
* supplies default values for the view, used only if
* defStyleAttr is 0 or can not be found in the theme. Can be 0
* to not look for defaults.
* @see #View(Context, AttributeSet, int)
*/
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes)
这四个构造函数在源码中都有注释,为了便于理解,我将注释也贴了出来,有点长,不过利于本文理解。
二 构造函数的调用
【第一个问题】
如果我们在继承了View类实现自定义类时,需要重写哪个构造函数?
回答这个问题,首先需要知道,在定义了View时,我们都调用了哪个构造函数。我这里做了一个简单的实验:
我们声明一个简单的View,继承自TextView,什么都不改,只是在4个constructor中打印几个tag,查看到底哪个构造函数被调用。
【实验】
package com.zhaohui.code.view;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
import com.example.zhaohui.player.R;
/**
* Created by zhaohui on 16-8-12.
*/
public class CustomView extends TextView {
String tag = "customView";
public CustomView(Context context) {
super(context);
Log.d(tag,"First Constructor");
}
public CustomView(Context context, AttributeSet attrs) {
this(context,attrs,android.R.attr.textViewStyle);
Log.d(tag,"Second Constructor");
for(int i=0;i<attrs.getAttributeCount();i++){
Log.d(tag, attrs.getAttributeName(i)+" : "+attrs.getAttributeValue(i));
}
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr,0);
Log.d(tag,"Third Constructor");
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr,defStyleRes);
Log.d(tag,"Fourth Constructor");
}
}
在布局文件layout中加上这个View
<com.zhaohui.code.view.CustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CustomView"
android:textSize="30sp"/>
[实验结果]
08-14 05:08:37.847 13687-13687/com.example.zhaohui.player D/customView: Second Constructor
08-14 05:08:37.847 13687