摘自安卓开发艺术探索第四章
1.自定义View的分类
(1)继承View重写onDraw方法
这种方法主要用于实现一些不规则的效果,即这种效果不方便通过布局的组合方式来达到,往往需要静态或者动态的显示一些不规则的图形。很显然这需要通过绘制的方式来实现,即重写onDraw方法。采用这种方式需要自己支持wrap_content,并且padding也需要自己处理。
(2)继承ViewGrope派生特殊的layout
这种方法主要用于实现自定义的布局,即除了LinearLayout、RelativeLayout、frameLayout这几种系统的布局之外,我们重新定义一种新布局,当某种效果看起来很像几种View组合在一起的时候,可以采用这种方法来实现。采用这种方式稍微复杂一些,需要合适的处理ViewGrope的测量、布局这两个过程,并同时处理子元素的测量和布局过程。
(3)继承特定的View(比如TextView)
这种方法比较常见,一般是用于扩展某种已有的View的功能,比如TextView,这种方法比较容易实现。这种方法不需要自己支持wrap_content和padding等。
(4)继承特定的ViewGrope(比如LinearLayout)
这种方法也比较常见,当某种效果看起来很像几种View组合在一起的时候,可以采用这种方式来实现。采用这种方法不需要自己处理ViewGroup的测量和布局这两个过程。需要注意这种方式和方法(2)的区别,一般来说方法(2)能实现的效果方法4也都能实现,两者的主要差别在于方法(2)更接近View底层
2.自定义View常见的注意事项
(1).让View支持wrap_content
这是因为直接继承View或者viewGroup的控件,如果不在onMeasure中对wrap_content做特殊处理,那么当外界在布局中使用wrap_content时就无法达到预期的效果,因为不重写onMeasure方法的话wrap_content和match_parent的处理是一样的。
(2)如果有必要,让你的View支持padding
这是因为直接继承View的控件,如果不在draw方法中处理padding,那么padding属性是无法起作用的。另外,直接继承自ViewGrope的控件需要在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带有滑动嵌套情形时,需要处理好滑动冲突