个人进阶之路——自定义控件(6)
2016-02-28 00:56
218 查看
Layout过程
Layout 作用:ViewGroup用来确定子元素的位置
位置确定后,在onLayout中遍历所有的子元素,调用其layout方法,在layout方法中onLayout方法又会被调用
Layout方法确定View本身的位置
onLayout方法确定所有子元素的位置
layout方法的大概流程:通过setFrame来设定View的四个顶点的位置,初始化mLeft等四个值。
View的是个顶点确定后,View在父容器中的位置确定,调用onLayout方法,父容器确定子元素的位置
onLayout的布局与具体的布局有关
View和ViewGroup均没有真正实现onLayout方法
将一下LinearLayout中的onLayout方法,其中的layoutVertical会遍历所有子元素并且调用setChildFrame,仅仅是调用子元素的Layout方法而已,完成layout定位后,通过onlayout方法去调用子元素的layout方法,子元素又会通过自己的layout方法来确定自己的位置,这样逐层传递,完成view树的layout。
SetChildFrame的width和height实际上是子元素的测量宽高
layout方法中会通过setFrame去设置子元素的四个顶点位置
View的测量宽高和最终宽高有什么区别?
View的getMeasuredWidth和getWidth方法有什么区别?
getWidth方法返回值刚好是View的测量宽度
在View的默认实现中,View的测量宽高和最终宽高是相等的
测量宽高形成于View的Measure过程
最终宽高形成于View的layout过程
两者的赋值时机不同,测量宽高的赋值时机会稍微早一点
日常开发中,可以认为View的测量宽高等于最终宽高,但是的确存在某些特殊情况会导致两者不一样
view需要多次measure才能确定自己的测量宽高
在前几次的测量过程中,其得出的侧量宽高有可能和最终宽高不一致,但是最终来说,测量宽高还是和最终宽高相同
draw过程
作用:将View绘制到屏幕上面
(1)绘制背景background.draw(canvas)
(2)绘制自己(onDraw)
(3)绘制children(dispatchDraw)
(4)绘制装饰(onDrawScrollBars)
View 的绘制过程的传递时通过dispatchDraw来实现的,通过遍历所有子元素的draw方法,如此draw事件就逐层的传递下去
setWillNotDraw,如果一个View不需要绘制任何内容,那么设置这个标记位为true后,系统会进行相应优化。
默认情况下,View没有启用这个优化标记位,但是ViewGroup会默认启动这个标记位
开发的实际 意义是:自定义控件继承于ViewGroup,并且本身不具备绘制功能时,可开该标记位,便于系统进行后续的优化
当明确知道一个ViewGroup需要通过onDraw来绘制内容时,需要显示地关闭WILL_NOT_DRAW标记位
自定义View分类
1、继承View 重写onDraw方法
实现一些不规则的效果,该效果不方便通过布局的组合方式来达到
往往需要静态或动态显示一些不规则的图形
需要通过绘制的方式来实现,重写onDraw方法
采用该方式,需要自己支持wrap_content,并且padding也需要自己处理
2、继承ViewGroup派生特殊的Layout
主要用于实现自定义的布局,除了系统的布局外,重新定义的一种新布局
该方式稍微复杂些,需要合适地处理ViewGroup的测量,布局这两个过程,并同时处理子元素的测量和布局过程
3、继承特定的View(TextView)
方法比较常见,用于扩展某种已有的view的功能,比较容易实现,不需要自己支持wrap_content和padding
4、继承特定的ViewGroup(LinearLayout)
方法比较常见,当某种效果看起来很像几种View组合在一起的时候,可以采用这种方式实现,
采用该方法不需要自己处理ViewGroup的测量和布局。
注意和方法2的区别,一般来说,方法2能实现的效果4也都能实现。两者的区别是,方法2更接近于View底层
自定义View过程中常见的注意事项
1、让View支持wrap_content
直接继承View或者ViewGroup的控件,如果不在onMeasure中对wrap_content做特殊处理,那么当外界在布局中使用wrap_content时就无法达到预期的效果
2、如果有必要,让你的view支持padding
直接继承view的控件,如果不在draw方法中处理padding,那么padding属性是无法起作用的。
直接继承自ViewGroup的控件需要在onMeasure和onLayout中考虑padding和子元素的margin对其造成的影响,不然将导致padding和子元素的margin失效
3、尽量不要在View中使用Handler,没有必要
View内部本身就提供post系列的方法,完全可以替代Handler的作用,除非明确要使用handler来发送消息
4、View中如果有线程或者动画,需要及时停止,参考View#onDetachedFromWindow
如果有线程或者动画需要停止时,onDetachedFromWindow是一个好时机,
当包含此View的Activity退出或者当前View被remove时,View的onDetachedFromWindow方法被调用,
对应于onAttachedToWindow,当包含此View的Activity启动时,View的onAttachedToWindow方法会被调用。
同时,当View变得不可见时,需要停止线程和动画,如果不及时处理这种问题,有可能会造成内存泄露。
5、View带有滑动嵌套情形时,需要处理好滑动冲突
如果有滑动冲突的话,适合地处理滑动冲突,否则将会严重影响View的效果
Layout 作用:ViewGroup用来确定子元素的位置
位置确定后,在onLayout中遍历所有的子元素,调用其layout方法,在layout方法中onLayout方法又会被调用
Layout方法确定View本身的位置
onLayout方法确定所有子元素的位置
layout方法的大概流程:通过setFrame来设定View的四个顶点的位置,初始化mLeft等四个值。
View的是个顶点确定后,View在父容器中的位置确定,调用onLayout方法,父容器确定子元素的位置
onLayout的布局与具体的布局有关
View和ViewGroup均没有真正实现onLayout方法
将一下LinearLayout中的onLayout方法,其中的layoutVertical会遍历所有子元素并且调用setChildFrame,仅仅是调用子元素的Layout方法而已,完成layout定位后,通过onlayout方法去调用子元素的layout方法,子元素又会通过自己的layout方法来确定自己的位置,这样逐层传递,完成view树的layout。
SetChildFrame的width和height实际上是子元素的测量宽高
layout方法中会通过setFrame去设置子元素的四个顶点位置
View的测量宽高和最终宽高有什么区别?
View的getMeasuredWidth和getWidth方法有什么区别?
getWidth方法返回值刚好是View的测量宽度
在View的默认实现中,View的测量宽高和最终宽高是相等的
测量宽高形成于View的Measure过程
最终宽高形成于View的layout过程
两者的赋值时机不同,测量宽高的赋值时机会稍微早一点
日常开发中,可以认为View的测量宽高等于最终宽高,但是的确存在某些特殊情况会导致两者不一样
view需要多次measure才能确定自己的测量宽高
在前几次的测量过程中,其得出的侧量宽高有可能和最终宽高不一致,但是最终来说,测量宽高还是和最终宽高相同
draw过程
作用:将View绘制到屏幕上面
(1)绘制背景background.draw(canvas)
(2)绘制自己(onDraw)
(3)绘制children(dispatchDraw)
(4)绘制装饰(onDrawScrollBars)
View 的绘制过程的传递时通过dispatchDraw来实现的,通过遍历所有子元素的draw方法,如此draw事件就逐层的传递下去
setWillNotDraw,如果一个View不需要绘制任何内容,那么设置这个标记位为true后,系统会进行相应优化。
默认情况下,View没有启用这个优化标记位,但是ViewGroup会默认启动这个标记位
开发的实际 意义是:自定义控件继承于ViewGroup,并且本身不具备绘制功能时,可开该标记位,便于系统进行后续的优化
当明确知道一个ViewGroup需要通过onDraw来绘制内容时,需要显示地关闭WILL_NOT_DRAW标记位
自定义View分类
1、继承View 重写onDraw方法
实现一些不规则的效果,该效果不方便通过布局的组合方式来达到
往往需要静态或动态显示一些不规则的图形
需要通过绘制的方式来实现,重写onDraw方法
采用该方式,需要自己支持wrap_content,并且padding也需要自己处理
2、继承ViewGroup派生特殊的Layout
主要用于实现自定义的布局,除了系统的布局外,重新定义的一种新布局
该方式稍微复杂些,需要合适地处理ViewGroup的测量,布局这两个过程,并同时处理子元素的测量和布局过程
3、继承特定的View(TextView)
方法比较常见,用于扩展某种已有的view的功能,比较容易实现,不需要自己支持wrap_content和padding
4、继承特定的ViewGroup(LinearLayout)
方法比较常见,当某种效果看起来很像几种View组合在一起的时候,可以采用这种方式实现,
采用该方法不需要自己处理ViewGroup的测量和布局。
注意和方法2的区别,一般来说,方法2能实现的效果4也都能实现。两者的区别是,方法2更接近于View底层
自定义View过程中常见的注意事项
1、让View支持wrap_content
直接继承View或者ViewGroup的控件,如果不在onMeasure中对wrap_content做特殊处理,那么当外界在布局中使用wrap_content时就无法达到预期的效果
2、如果有必要,让你的view支持padding
直接继承view的控件,如果不在draw方法中处理padding,那么padding属性是无法起作用的。
直接继承自ViewGroup的控件需要在onMeasure和onLayout中考虑padding和子元素的margin对其造成的影响,不然将导致padding和子元素的margin失效
3、尽量不要在View中使用Handler,没有必要
View内部本身就提供post系列的方法,完全可以替代Handler的作用,除非明确要使用handler来发送消息
4、View中如果有线程或者动画,需要及时停止,参考View#onDetachedFromWindow
如果有线程或者动画需要停止时,onDetachedFromWindow是一个好时机,
当包含此View的Activity退出或者当前View被remove时,View的onDetachedFromWindow方法被调用,
对应于onAttachedToWindow,当包含此View的Activity启动时,View的onAttachedToWindow方法会被调用。
同时,当View变得不可见时,需要停止线程和动画,如果不及时处理这种问题,有可能会造成内存泄露。
5、View带有滑动嵌套情形时,需要处理好滑动冲突
如果有滑动冲突的话,适合地处理滑动冲突,否则将会严重影响View的效果
相关文章推荐
- trie+dp+打印路径 Codeforces633C Spy Syndrome 2
- 随笔就随笔
- 《道德经•第六十三章》体悟
- 2016-02-28 00:53:21 version 与build
- 2016-2-27补写
- 关于Hybrid app架构的思考
- volley的用法(数据库网络请求框架 )
- Python基础0228
- Https socket 代理
- Runloop的原理和核心机制
- Delphi一共封装(超类化)了8种Windows基础控件和17种复杂控件
- Asp.Net sqlmetal 笔记
- VMware Workstation下VMnet1等虚拟网卡与主机网卡之间的关系
- build-tools\21.1.2\aapt.exe finished with non- zero exit value 1错误
- 玩转Red5+Flex(4)—— Red5配置文件之解说
- HDU 4605 Magic Ball Game(离线、BIT)
- Java调用ffmpeg进行视频转码
- 问卷调查
- ASP.NET Web API中的参数绑定总结
- cookie技术核心! 就是四个类的应用 搞懂这个基本上就把这个搞定了!