Why: 为什么要自定义控件
- 特定的显示风格
- 处理特有的用户交互
- 优化我们的布局
- 封装等...
How: 如何自定义控件
- 自定义属性的声明与获取
- 分析需要的自定义属性
- 在
res/values/attrs.xml
定义声明 - 在
layout.xml
文件中进行使用 - 在View的构造方法中进行获取
- 测量onMeasure
- MeasureSpec Mode:EXACTIY(明确的:具体数值及matchparent,且不超过父控件),AT_MOST(wrapcontent,至多不超过),UNSPECIFIED(不限制高度,一般用于scrollview及listview中)
- MeasureSpec Size
- setMeasureDimension
- requestLayout() (重新触发测量及布局)
- 测量onLayout(ViewGroup)
- 决定子View的位置
- 尽可能将onMeasure中一些操作移动到此方法中
- requestLayout() (重新触发测量及布局)
- 绘制onDraw
- 绘制内容区域
- invalidate() , postInvalidate()
- Canvas.drawXXX
- translate,rotate,sclae,skew
- save(),restore()
- onTouchEvent (ViewGroup)
- ACTION_DOWN , ACTION_MOVE , ACTION_UP
- ACTION_POINT_DOWN,ACTION_POINT_UP
- parent.requestDisallowInterceptTouchEvent(true) (请求父控件不要拦截手势)
- VelocityTracker
- onInterceptTouchEvent(ViewGroup) (如果本方法返回true代表本方法把子View的时间拦截了)
- ACTION_DOWN,ACTION_MOVE,ACTION_UP
- ACTION_POINTER_DOWN,ACTION_POINTER_UP
- 其他
- onSaveInstanceState,onRestoreInstanceState
- ViewConfiguration (mTouckSlop等)
- ScaleGestureDetector,ViewDragHelpe