背景介绍
前面两章我们介绍了View的大致的绘制流程,有需要的朋友可以去看我之前的内容,也可以浏览下面的链接,查看详细的介绍,个人感觉写的挺完整的:View的绘制流程。这里主要讲一下自定义View的类型。
自定义View的分类
1. 继承重写onDraw方法
这种方法一般用来实现一些不规则的效果,即效果不方便通过一般的布局来实现,我们只需要重写onDraw方法即可,采用这种方式要自己支持warp_content,并且需要自己处理padding。
2. 集成ViewGroup派生特殊的Layout
这种方式一般用来实现自定义布,即除了LinerLayout、RelativrLayout和FrameLayout之外的布局,我们需要重新定义一种新的布局,当某种效果看起来像多个View组合在一起的时候我们可以采用这种方法,采用这种方式需要合适地处理ViewGroup的测量和布局,这两个过程,并同时处理子元素的测量和布局。
3. 集成特定的View(比如Button)
这种方法比较常见,用来扩展某种已有View的功能,,这种方法实现比较容易,不需要自己支持warp_content和padding等。
4. 继承特定的ViewGroup (比如LinerLayout)
这种方法也比较常见,也可以用来实现看起来像集中View组合在一起的效果,并且不需要自己处理ViewGroup的测量和布局,它跟方法二比较类似,一般来说方法二可以实现的它也可以实现,只是方法二更接近于View的底层。
自定义View须知
上面介绍的集中方法,我们可以仔细体味一下,自定义View讲究的是灵活性,一般某种样式多个方法都可以实现,我们需要比较各自的优缺点,找到代价小,效率高的方法来实现它。
1. 让View支持warp_content
因为直接继承View或者ViewGroup的控件如果不在onMeasure中队warp_content做特殊处理的话,当外界布局使用的时候就无法达到预期的效果。
2. 如果有必要,让你的View支持padding
因为直接继承View的控件,如果不在draw方法里面处理padding的话,那么padding的属性是不起作用的,另外直接继承ViewGroup的空间需要在onMeasure和onLayout中考虑padding和子元素的marging对其造成的影响,否则会导致padding和子元素的marging失效。
3. 尽量不要在View中使用Handle
View内部本身提供了post系列的方法,几乎可以完全替代Handle。
4. 如果View中有线程或者动画需要及时停止,参考View#onDetachedFromWindow
因为当包含此View的Activity退出或者View被remove掉的时候View的onDetachedFromWindow方法会被调用,和此方法对应的是onAttachedToWindow,当View的Activity启动或View被显示在屏幕内时会被调用,我们要在对应的方法中及时的做一些处理,防止内存泄漏。
5. View带有滑动嵌套,需要谨慎处理冲突
保证效果流程,要处理好滑动冲突。
网友评论