通常开发Android应用程序的界面时,都不直接使用View控件,而是使用View控件的子类。例如,如果要显示一段文字,可以使用View控件的子类TextView控件;如果要显示一个按钮,可以使用View控件的子类Button控件。虽然Android提供了很多继承自View类的控件,但是在实际开发中,还会出现不满足需求的情况,此时我们可以通过自定义控件的方式实现。最简单的自定义控件就是创建一个继承View或其子类的类 ( app / java / 包名 / xxx.java ) ,并重写该类的构造方法。
实例代码如下:
public class MyView extends View {
public MyView(Context context) {
super(context);
//在Java代码中使用的方法
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
//在XML布局文件中使用的方法
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//该方法用于测量尺寸,在该方法中可以设置控件本身或其子控件的宽高
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//该方法用于绘制图像
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//用于指定布局中子控件的位置
}
//其他自定义控件的方法
}
public XXX( Context context )方法是在Java文件中使用的构造方法,public XXX( Context context , AttributeSet attrs )方法是在XML布局文件中使用的方法。
由于系统自带的控件不能满足需求中的某种样式或功能,所以我们需要在自定义控件中通过重写指定的方法来添加额外的样式和功能。自定义控件常用的3个方法的具体介绍如下:
该方法用于测量尺寸,在该方法中可以设置控件本身或其子控件的宽高,onMeasure()方法的具体介绍如下:
onMeasure( int widthMeasureSpec , int heightMeasureSpec )
onMeasure()方法中第一个参数widthMeasureSpec表示获取父容器指定的该控件宽度,第二个参数heightMeasureSpec表示获取父容器指定的该控件高度。
widthMeasureSpec和heightMeasureSpec参数不仅包含父容器指定的属性值,还包含父容器的测量模式,测量模式分为三种,具体介绍如下:
EXACTLY:当自定义控件的宽高值设置为具体值时使用,如100dp、match_parent等,此时控件的宽高值是精确的尺寸。
AT_MOST:当自定义控件的宽高值为wrap_content时使用,此时控件的宽高值是控件中的数据内容可获得的最大空间值。
UNSPECIFIED:当父容器没有指定自定义控件的宽高值时使用。
需要注意的是,虽然参数widthMeasureSpec和heightMeasureSpec是父容器为该控件指定的宽高,但是该控件还需要通过 setMeasureDimension( int i , int i ) 方法设置具体的宽高。
该方法用于绘制图像,onDraw()方法的具体介绍如下:
onDraw( Canvas canvas )
onDraw()方法中的参数canvas表示画布。Canvas类(画布)经常与Paint类(画笔)配合使用,使用Paint类可以在Canvas类中绘制图像。
onLayout()方法用于指定布局中子控件的位置,该方法通常在自定义的ViewGroup容器中重写。
onLayout()方法的具体介绍如下:
onLayout( boolean changed , int left , int top , int right , int bottom )
onLayout()方法中有5个参数,其中第1个参数changed表示自定义控件的大小和位置是否发生变化,剩余的4个参数left、top、right、bottom分别表示子控件与父容器左边、顶部、右边、底部的距离。