Android自定义控件

在开发过程中因为产品或者UI一些不同于Google标准的设计时经常需要用到自定义View(也叫自定义控件), 或者对于某种功能控件的封装. 这里总结下我是如何学习自定义View的.

流程

自定义View一般都直接或者间接继承View, 所以可以达到重写View中的某些方法实现自己的自定义控件

大致流程分为三步, 同时对应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
public class CustomView extends View {
/**
* 自定义控件必须传入上下文
*
* @param context
*/
public CustomView(Context context) { super(context); }
/**
* 如果想在xml布局文件中使用自定义控件必须重写构造方法
*
* @param context
* @param attrs xml布局文件中使用的属性
*/
public CustomView(Context context, AttributeSet attrs) { super(context, attrs); }
/**
* 增加样式
* @param context
* @param attrs
* @param defStyleAttr 控件样式
*/
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
/**
* 在api21后增加的构造方法
* @param context
* @param attrs
* @param defStyleAttr
* @param defStyleRes
*/
public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); }
}

测量

onMeasure()

View中一个的重要的方法, 负责View的绘制.

MeasureSpec

View中的内部类, 表示绘制规格说明, 该内部类是绘制过程中的关键类

提供三个公开方法

1
2
3
4
5
6
7
static int getMode(int measureSpec) // 得到模式
static int getSize(int measureSpec) // 得到尺寸
static int makeMeasureSpec(int size, int mode) // 自定义尺寸和模式
static String toString(int measureSpec)

测量模式一共有三种, 被定义在 Android 中的 View 类的一个内部类View.MeasureSpec中:

模式 二进制数值 描述
UNSPECIFIED 00 默认值,父控件没有给子view任何限制,子View可以设置为任意大小。
EXACTLY 01 表示父控件已经确切的指定了子View的大小。
AT_MOST 10 表示子View具体大小没有尺寸限制,但是存在上限,上限一般为父View大小。

如果对View的宽高进行修改了,不要调用 super.onMeasure( widthMeasureSpec, heightMeasureSpec); 要调用 setMeasuredDimension( widthsize, heightsize); 这个函数

1
setMeasuredDimension(200, 200);

绘制

更新视图

1
2
postInvalidate(); // 异步加载视图更新 -- 主线程更新UI
Invalidate() // 同步加载视图更新