Android自定义View控件
2016-03-08 17:52
507 查看
转自:http://blog.csdn.net/lvwenbo0107/article/details/50542597
为什么要自定义控件
1.特定的显示风格。
2.处理特有的用户交互。(textView支持一些滑动功能)
3.优化我们的布局。(嵌套布局绘制比较慢)
4.封装。(tab页按钮不好看)
如何自定义控件
1.自定义属性声明与获取。
2.测量onMeasure。
3.布局onLayout(ViewGroup才需要)
4.绘制onDraw
5.onTouchEvent
6.onInterceptTouchEvent(ViewGroup)
一.自定义属性声明与获取
二.测量onMeasure
由测量模式跟测量值决定测量的大小。
1.模式:
EXATLY(明确的值)
AT_MOST(至多不能超过某个值,一般出现在设置wrap_content,控件大小有自身决定但不能超过父控件的尺寸)
UNSPECIFIED(无限制,比如scrollView,ListView的子View的高度)
2.测量的值
MeasureSpec 辅助类 封装了测量模式跟测量值,由父控件传递下来,通过getMode获取模式,通过getSize获取值
获取到的result需要调用setMeasuredDimension
如果想要重新测量,则调用对外提供一个A(){requestLayout() 重新测量measure和布局onlayout}
invalidate 触发绘制
三.布局onLayout(ViewGroup)父控件决定子控件的显示使用(只会触发一次)
1.决定子View的位置。
2.尽可能将onMeasure中一些(耗时,初始化)操作移动到此方法中(只会触发一次)。
3.requestLayout() 来触发[b]onLayout[/b]
四.绘制onDraw
1.绘制内容区域
2.重绘:invalite() UI线程调用 postInvalidate() 子线程调用;
3.Canvas.drawXXX
4.translate rotate scale skew (canvas 变换)
5.save() restore()(变换后保存还原)
自定义控件如果没有跟用户的交互则只需要考虑onMeasure,onDraw ,自定义容器需要考虑onMeasure,onLayout,一般不考虑onDraw
五.onTouchEvent
velocityTracker 用来追踪触摸事件(flinging事件和其他手势事件)的速率
pareent.requestDisallowInterceptTouchEvent(true) 子控件通知父控件不要拦截整个手势(down->up)由子控件处理手势
Action_point_down/up 多点触控
六.onInterceptTouchEvent(ViewGroup)
事件传递机制下父控件交给子控件去处理的,在转发的过程中父控件由权利拦截子控件的事件。
返回true 则代表拦截子控件事件,交给ViewGroup自己去处理。
决定是否拦截该手势(down->up)
七.还有什么?
1.onSaveInstanceState :这个是控件层的具体参考仿微信6.0案例 onChangeIconColor.onRestoreInstanceState
2.ViewConfiguration:获取控件常量。eg:mTouchSlop
3.ScaleGestureDetector 缩放手势
....
比如:
View-我要去分析这个View,他需要那些自定义的属性我要去编写,然后去自定义View的构造方法中去获取。
我会重写他测量的方法,决定我们View占据的空间,测量完成后我会复写onDraw方法,决定我们的View到底
展示成一个什么样的形态。
ViewGroup-首先测量自身大小,还有子View的大小,然后复写onLayout决定子View放置的规则,如果有
用户交互需要重写onTouchEvent,决定如何交互,onInterceptTouchEvent决定是否拦截子View。
为什么要自定义控件
1.特定的显示风格。
2.处理特有的用户交互。(textView支持一些滑动功能)
3.优化我们的布局。(嵌套布局绘制比较慢)
4.封装。(tab页按钮不好看)
如何自定义控件
1.自定义属性声明与获取。
2.测量onMeasure。
3.布局onLayout(ViewGroup才需要)
4.绘制onDraw
5.onTouchEvent
6.onInterceptTouchEvent(ViewGroup)
一.自定义属性声明与获取
二.测量onMeasure
由测量模式跟测量值决定测量的大小。
1.模式:
EXATLY(明确的值)
AT_MOST(至多不能超过某个值,一般出现在设置wrap_content,控件大小有自身决定但不能超过父控件的尺寸)
UNSPECIFIED(无限制,比如scrollView,ListView的子View的高度)
2.测量的值
MeasureSpec 辅助类 封装了测量模式跟测量值,由父控件传递下来,通过getMode获取模式,通过getSize获取值
获取到的result需要调用setMeasuredDimension
如果想要重新测量,则调用对外提供一个A(){requestLayout() 重新测量measure和布局onlayout}
invalidate 触发绘制
三.布局onLayout(ViewGroup)父控件决定子控件的显示使用(只会触发一次)
1.决定子View的位置。
2.尽可能将onMeasure中一些(耗时,初始化)操作移动到此方法中(只会触发一次)。
3.requestLayout() 来触发[b]onLayout[/b]
四.绘制onDraw
1.绘制内容区域
2.重绘:invalite() UI线程调用 postInvalidate() 子线程调用;
3.Canvas.drawXXX
4.translate rotate scale skew (canvas 变换)
5.save() restore()(变换后保存还原)
自定义控件如果没有跟用户的交互则只需要考虑onMeasure,onDraw ,自定义容器需要考虑onMeasure,onLayout,一般不考虑onDraw
五.onTouchEvent
velocityTracker 用来追踪触摸事件(flinging事件和其他手势事件)的速率
pareent.requestDisallowInterceptTouchEvent(true) 子控件通知父控件不要拦截整个手势(down->up)由子控件处理手势
Action_point_down/up 多点触控
六.onInterceptTouchEvent(ViewGroup)
事件传递机制下父控件交给子控件去处理的,在转发的过程中父控件由权利拦截子控件的事件。
返回true 则代表拦截子控件事件,交给ViewGroup自己去处理。
决定是否拦截该手势(down->up)
七.还有什么?
1.onSaveInstanceState :这个是控件层的具体参考仿微信6.0案例 onChangeIconColor.onRestoreInstanceState
2.ViewConfiguration:获取控件常量。eg:mTouchSlop
3.ScaleGestureDetector 缩放手势
....
比如:
View-我要去分析这个View,他需要那些自定义的属性我要去编写,然后去自定义View的构造方法中去获取。
我会重写他测量的方法,决定我们View占据的空间,测量完成后我会复写onDraw方法,决定我们的View到底
展示成一个什么样的形态。
ViewGroup-首先测量自身大小,还有子View的大小,然后复写onLayout决定子View放置的规则,如果有
用户交互需要重写onTouchEvent,决定如何交互,onInterceptTouchEvent决定是否拦截子View。
相关文章推荐
- Android 判断数据库中是否存在某个表
- Android 6.0 运行时权限处理完全解析
- Android SDKManger 更新设置
- android开源框架
- Android Binder机制 (1~12)
- Android在线中文API
- 奇葩的Android Bug: Unable to start service Intent
- Android自动清理 无用 多余 未引用 未关联资源工具
- Android Binder机制(三) ServiceManager守护进程
- Android 开发者的 RxJava 详解
- Android Design支持库TabLayout 来实现tab效果
- Android Binder机制(一) Binder的设计和框架
- Android Cordova 插件开发之插件开发过程中遇到的问题
- Android Checkbox详解
- android里R.layout.的问题
- Android之ViewTreeObserver
- android Json解析详解(详细代码)
- android studio 打包混淆jar
- android Matrix图片手势放大缩小,拖动
- Android的classloader