一、自定义View
Android系统内置的View无法满足业务需求,需要自定义。
Step 1 : 继承View
|
|
至少写2个构造函数
Step 2 : 自定义属性
有些属性希望由用户指定,只有当用户不指定的时候才用我们硬编码的值,比如默认的宽高,在res/values/styles.xml文件里声明:
布局文件activity_main.xml中使用自定义的属性
构造器中读取配置信息并初始化
Step 3 : 重写onMeasure()
测量宽高尺寸并设置需要的值。如果不需要制定自定义控件的宽高,无需重写此方法。
- onMeasure()至少会被调用两次,第一次读取xml文件中的参数layout_width和layout_width,它们可以不用指定具体的尺寸,如值为wrap_content或match_parent。为了更好的适配各种尺寸的屏幕,需要根据父类布局或子类控件宽高动态计算实际宽高,而不是在xml中指定具体的数值。
- widthMeasureSpec和heightMeasureSpec都是int,前面2个bit用于区分不同的测量模式,后面30个bit存放的是尺寸的数据。测量模式分三种:UNSPECIFIED(父容器没有对当前View有任何限制,当前View可以任意取尺寸)、EXACTLY(当前的尺寸就是当前View应该取的尺寸,对应match_parent和固定值)、AT_MOST(当前尺寸是当前View能取的最大尺寸,对应wrap_content)
Step 4 : 重写onDraw()
|
|
效果图
完整代码
|
|
二、自定义ViewGroup
模拟一个简易垂直布局,详情可参考Android内置的LinearLayout源码。
Step 1 : 继承ViewGroup
必须实现onLayout(boolean changed, int left, int top, int right, int bottom)方法,用于“摆放”各个子View。
Step 2 : 自定义属性(同上)
Step 3 : 重写onMeasure()
|
|
Step 4 : 重写onLayout()
|
|
配置文件
|
|