转载请注明出处:http://blog.csdn.net/mybeta/article/details/39993449
我们都知道,在Android中要使用一个View,一般会有两种方式:1. 在XML文件中配置;2. 直接在代码中new一个View的对象。我们今天讨论的内容就是围绕着View的构造方法的。
1. 示例。
首先我们先来看一个例子。
新建一个工程,layout文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="(Context, AttributeSet)" />
</LinearLayout>
Activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.three_button_layout);
Button btn1 = new Button(this);
btn1.setText("(Context)");
Button btn2 = new Button(this, null, 0);
btn2.setText("(Context, AttributeSet, int)");
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
layout.addView(btn1);
layout.addView(btn2);
}
在layout文件中有一个Button,然后在代码中new了两个Button,并且添加到layout文件中,显示结果如下:
很显然,前面两个Button样式是一样的,并且默认可以点击,第3个Button就有点奇怪了,而且还无法点击。为什么会出现这种现象呢?这就是这篇文章要说明的问题了。
2. View构造函数。
要想理解上面的问题,我们必须先得了解View的构造函数。默认情况下,View有3个构造函数,函数原型如下:
public View(Context context);
public View(Context context, AttributeSet attrs);
public View(Context context, AttributeSet attrs, int defStyle);
如果要在代码中new一个View对象,我们一般会使用第一个构造函数。如果是在XML文件中声明的View,系统会默认调用第二个构造函数。而对于第三个构造函数,我们在自己的代码中一般都没有去调用它。
在上面的例子中,btn2这个Button正是采用的第三种构造方法创建出来的,结果导致了很奇怪的结果。既然是用Button做的例子,我们来看下Button的源码(Button的源码可以说是所有Android自带控件中最简单的了吧):【以下所有源码均基于Android2.2】
public class Button extends TextView {
public Button(Context context) {
this(context, null);
}
public Button(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.buttonStyle);
}
public Button(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
我们可以看到,整个类中仅仅只有3个构造方法,但是它继承自TextView,所以它的各种方法都是在TextView中实现的。然而,我们平时看到的TextView和Button还是有很多地方不同的,那是什么地方导致的这些差异呢?
显然,除了第二个构造方法中的com.android.internal.R.attr.buttonStyle,不可能有其他地方来区分TextView和Button了。而这里第二个构造方法调用了第三个构造方法,第三个构造比第二个构造方法多了一个int类型的参数。这就是关键所在了。
3. View构造方法中的第三个参数。
我们来看一下第三个构造方法的注释:官方文档
Perfo