赞
踩
都说学习自定义View开发都是:动画->绘图->事件分发->自定义布局(View的绘制过程)->自定义控件;由此学习是一个我认为比较愉快的学习方向。
首先说说自定义View的种类,分为三种:
1、组合控件:顾名思义,就是将一些小的控件组合起来形成的新控件,这些小控件可以是系统自带的控件,也可以是自定义的控件和系统控件混合组成;简单的操作就是新建一个XML布局文件,将我们想要的控件搭配放入我们的布局中,位置等我们可以按需设置。最常见的莫过于我们几乎每个页面布局中顶部的标题状态栏了,如果页面多起来要我们每个页面重复写相同的布局代码想必每个人都要疯吧,反正我是想撞墙,所以将标题状态栏抽离出来形成一个自定义的组合控件。相关文章解释
2、继承已有控件:继承已有的控件或者布局来创建新控件,可以保留父控件已有的特性,新增引入新的特性,省去了自绘控件带来的测量、布局带来的出错率,因为父控件已经帮我们实现了这些操作。可以继承TextView,ImageView,LinearLayout等。文章解释
3、自绘控件:新建类通过继承View或ViewGroup生成新控件,这种控件可以说是最难的一种了;在自定义控件内部,通过画笔(Paint)和画布(Canvas)绘制控件,需要掌握绘图知识,事件分发,以及View的测量、布局、绘制等。知识的掌握需要比较牢固和广泛。文章解释
在第三种自绘控件中有几点小知识我觉得有必要提一下:
1、postInvalidate()和invadite()刷新控件的区别,这里简单说一下:invadite()必须在主线程中调用,而postInvalidate()内部是由Handler的消息机制实现的,所以在任何线程都可以调用,但实时性没有invadite()强。但是一般为了保险起见,是使用postInvalidate()来刷新界面。
2、onDraw、dispatchDraw区别
onDraw()的意思是绘制视图自身,dispatchDraw()是绘制子视图,无论是View还是ViewGroup对它们俩的调用顺序都是onDraw()->dispatchDraw()。
但在ViewGroup中,当它有背景的时候就会调用onDraw()方法,否则就会跳过onDraw()直接调用dispatchDraw();所以如果要在ViewGroup中绘图时,往往是重写dispatchDraw()方法。
在View中,onDraw()和dispatchDraw()都会被调用的,所以我们无论把绘图代码放在onDraw()或者dispatchDraw()中都是可以得到效果的,但是由于dispatchDraw()的含义是绘制子控件,所以原则来上讲,在绘制View控件时,我们是重写onDraw()函数
得出结论:在绘制View控件时,需要重写onDraw()函数,在绘制ViewGroup时,需要重写dispatchDraw()函数。
3、在View的onDraw中super.onDraw(canvas)和super.dispatchDraw(canvas)都是一个空实现,无影响;但是在ViewGroup中super.onDraw(canvas)和super.dispatchDraw(canvas)相反都为非空实现,如果先做super.dispatchDraw(canvas),再做其它绘图操作的结果是:先把子View绘制出来,然后再画你的绘画操作,这样可能会造成你的绘画操作把子View给覆盖上; 相反,先做你的绘画操作然后再调用super.dispatchDraw(canvas)的结果是:先把的绘画操作给画出来,然后再画子View,子View会把的绘画操作结果给覆盖上。
作者:木溪bo
链接:https://www.jianshu.com/p/009c9ce14d5a
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。