乘风破浪

android自定义view

为什么要自定义控件:
1、特定的显示风格
2、处理特有的用户交互
3、优化我们的布局
4、封装等…

如何自定义控件:

1、自定义属性的声明与获取
2、测量onMeasure
3、布局onLayout(ViewGroup)
4、绘制onDraw
5、onTouchEvent
5、onInterceptTouchEvent (ViewGroup)

自定义属性的声明与获取

1、分析需要的自定义属性
2、在res/values/attrs.xml定义声明
3、在layout.xml文件中进行使用
4、在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
<resources>
// 自定义TextView
<declare-styleable name="TextView">
// name 是名称,format是格式 color(颜色),string(文本),dimension(sp,dp)...
<attr name="textColor" format="color"/>
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
</declare-styleable>
</resources>
```
```
public TextView(Context context) {
this(context,null);
}
public TextView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public TextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 获取TypedArray
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.TextView);
// 获取文本
mText = typedArray.getText(R.styleable.TextView_text);
// 获取文字颜色
mTextColor = typedArray.getColorStateList(R.styleable.TextView_textColor);
// 获取文字大小
mTextSize = typedArray.getDimensionPixelSize(R.styleable.TextView_textSize,mTextSize);
// 回收
typedArray.recycle();
}

onMeasure
1、EXACTLY, AT_MOST, UNSPECIFIED
2、MeasureSpec
3、setMeasuredDimension
4、requestLayout()

onLayout(ViewGroup)
1、决定子View的位置
2、尽可能将onMeasure中一些操作移动到此方法
3、requestLayout()

绘制onDraw
1、绘制内容区域
2、invalidate(), postInvalidate()
3、Canvas.drawXXX
4、translate、rotate、 scale、 skew
5、save(), restore()

onTouchEvent
onInterceptTouchEvent (ViewGroup)