Android自带的视图常常不能满足实际开发的需求,这种情况下我们就得自定义视图(View)。 首先在res\values目录下找到attrs.xml(如没有则创建之),在该属性定义文件的resources根节点下增加类似下面的定义:
<declare-styleable name="SignatureView">
<attr name="paint_color" format="color" />
</declare-styleable>
其次在代码中创建类似SignatureView的自定义视图类,编写代码并编译通过。 然后在使用自定义视图的布局文件的根节点下增加类似下面的命名空间定义,这里的路径应与AndroidManifest.xml的package属性值保持一致。
xmlns:app="http://schemas.android.com/apk/res/com.practice.activity"
最后在使用视图的xml布局中加上类似下面这样的xml描述:
<com.practice.widget.SignatureView
android:id="@+id/view_signature"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:paint_color="@color/blue" />
自定义视图的编码主要由四部分组成: 一、重写构造函数,并初始化个性化参数; 二、重写测量函数onMesure,计算该视图的宽与高(除了复杂视图,实际开发中一般不进行重写); 三、重写绘图函数onDraw、onLayout、dispatchDraw,视情况重写三个其中的一个或多个; 四、重写触摸事件函数dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent,一般情况不做重写,当然存在手势滑动冲突时,就必须重写; 以上四点,本章只记录前面三点,第四点事件函数这部分内容较复杂,留待后面的章节介绍。
自定义视图存在三个构造函数,分别是
//只有一个参数,用于在代码中构造对象
public SignatureView(Context context) {
super(context);
}
//有两个参数,用于在XML布局中构造对象
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
if (attrs != null) {
TypedArray attrArray=getContext().obtainStyledAttributes( attrs, R.styleable.SignatureView);
mPaintColor = attrArray.getColor(R.styleable.SignatureView_paint_color, 0);
attrArray.recycle();
}
}
//有三个参数,用于在XML布局中构造对象
public SignatureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
其中,在代码中构造对象时采用第一种构造函数,在XML布局中构造对象时采用第二种构造函数。第三个函数也是在XML布局中构造对象时使用,它与第二种的区别在于: 1、defStyleAttr是一种特殊的属性,其类型既非整型也非字符串,而是参照类型(reference,需要在style.xml中另外定义),举例如下:
<declare-styleable name="SignatureView">
<attr name="paint_color" format="color" />
</declare-styleable>
<attr name="CustomizeStyle" format="reference" />
2、XML布局直接调用的都是第二种构造,第三种构造都是通过第二种构造来调用,举例如下:
public SignatureView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.CustomizeStyle);
}
public SignatureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (attrs != null) {
TypedArray attrArray=getContext().obtainStyledAttributes( attrs, R.styleable.SignatureView, defStyleAttr, R.style.DefaultCustomizeStyle);
mPaintColor = attrArray.getColor(R.styleable.SignatureView_paint_color, 0);
attrArray.recycle();
}
}
这样Android在寻找该自定义视图的属性时,就会依次先找XML布局文件,再找attrs.xml文件中R.attr.CustomizeStyle的定义,最后找style文件中R.style.DefaultCustomizeStyle的定义。
个人感觉第三种构造函数在实际开发中用的不多,不需要过多的深入研究,了解了解就好了。