View的五个构造函数的区别
View()
,没有暴露出来,等于没有,过过过1
2
3
4
5
6
7/**
* Non-public constructor for use in testing
*/
View() {
mResources = null;
mRenderNode = RenderNode.create(getClass().getName(), this);
}
View(Context context)
,当在代码中创建view时使用,传入一个上下文,使该View运行在其中,并且可以通过这个上下文获取主题、资源等。1
2
3
4
5
6
7/**
* 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) {...}
- 从布局文件xml中填充出来的view使用这个2参的构造函数。
第1个参数context
上文说过了,第2个参数attr
包含了在xml中定义的属性,初始化的时候需要把这些属性拿出来用。可以看到这个构造直接调用了一个三参构造。那么继续走1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/**
* 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) {
this(context, attrs, 0);
}
- 三参构造2参构造会调用这个3参构造,多了一个默认样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/**
* 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) {
this(context, attrs, defStyleAttr, 0);
}defStyleAttr
,比如Button
的构造会传一个Button的样式,然后调用了自己的四参构造而四参构造会调用父类1
2
3public Button(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.buttonStyle);
}TextView
的四参构造,TextView
会继续调用父类View
的四参构造。所以这个三参构造的第三个参数1
2
3public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}defStyleAttr
是给View
的子类传自己用的属性配置的。
- 四参构造比三参多了个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41/**
* 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) {
this(context);
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
...
}defStyleRes
,子类在覆写构造的时候可以传入样式资源到这里。可以看到,四参构造也是先调用了this(context)
,然后获取到TypeArray
拿各种属性,再继续对view进行初始化操作。
#####总结:View(Context)是从代码中创建view走的构造。 View(Context,AttributeSet),是从xml中填充的view走的构造,2参会调用3参,3参调用4参,4参最后会调用1参,然后拿到所有属性再初始化。这样子类的构造可以传入特定的attr和style来初始化。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 七夜的小屋!