关于自定义View的一些东西
2013-06-06 20:43
309 查看
一、Android中View的绘制流程最近要做一个关于绘图的demo,不太清楚用什么方法来进行绘图,也不知道这个方法怎么进行绘图,这个方法的工作原理,于是上网找到了一些资料,在这里分享一下。整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为根据之前设置的状态,判断是否需要重新计算视图大小(measure)、是否重新需要安置视图的位置(layout)、以及是否需要重绘 (draw),其框架过程如下:
![](http://blog.51cto.com/attachment/201306/204202780.png)
流程一: mesarue()过程主要作用:为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性: mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。具体的调用链如下: ViewRoot根对象地属性mView(其类型一般为ViewGroup类型)调用measure()方法去计算View树的大小,回调View/ViewGroup对象的onMeasure()方法,该方法实现的功能如下: 1、设置本View视图的最终大小,该功能的实现通过调用setMeasuredDimension()方法去设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性:mMeasureWidth); 2 、如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。 2.1 对每个子视图的measure()过程,是通过调用父类ViewGroup.java类里的measureChildWithMargins()方法去实现,该方法内部只是简单地调用了View对象的measure()方法。(由于measureChildWithMargins()方法只是一个过渡层更简单的做法是直接调用View对象的measure()方法)。整个measure调用流程就是个树形的递归过程
流程二、 layout布局过程:主要作用 :为将整个根据子视图的大小以及布局参数将View树放到合适的位置上。具体的调用链如下: host.layout()开始View树的布局,继而回调给View/ViewGroup类中的layout()方法。具体流程如下: 1 、layout方法会设置该View视图位于父视图的坐标轴,即mLeft,mTop,mLeft,mBottom(调用setFrame()函数去实现)接下来回调onLayout()方法(如果该View是ViewGroup对象,需要实现该方法,对每个子视图进行布局) ; 2、如果该View是个ViewGroup类型,需要遍历每个子视图chiildView,调用该子视图的layout()方法去设置它的坐标值。
流程三、 draw()绘图过程由ViewRoot对象的performTraversals()方法调用draw()方法发起绘制该View树,值得注意的是每次发起绘图时,并不会重新绘制每个View树的视图,而只会重新绘制那些“需要重绘”的视图,View类内部变量包含了一个标志位DRAWN,当该视图需要重绘时,就会为该View添加该标志位。调用流程 : mView.draw()开始绘制,draw()方法实现的功能如下: 1 、绘制该View的背景 2 、为显示渐变框做一些准备操作(见5,大多数情况下,不需要改渐变框) 3、调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法) 4、调用dispatchDraw ()方法绘制子视图(如果该View类型不为ViewGroup,即不包含子视图,不需要重载该方法)值得说明的是,ViewGroup类已经为我们重写了dispatchDraw ()的功能实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能。 4.1dispatchDraw()方法内部会遍历每个子视图,调用drawChild()去重新回调每个子视图的draw()方法(注意,这个地方“需要重绘”的视图才会调用draw()方法)。值得说明的是,ViewGroup类已经为我们重写了dispatchDraw()的功能实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能。
二、如何自定义的View加入到布局中在解决了自定义View进行后绘图后,不知道怎么将这个View的实例添加到已经设定好的布局里,于是问了一下组长,找到了解决方法。举个实例:1.声明定义了一个LinearLayout的实例对象layout;2.声明定义了一个自定义View的实例对象view;3.使用layout.addView(view)就可以完成要求
4.GameView gameview =new GameView();5.// 定义了一个LinearLayout用来显示自定义的view6. LinearLayout layout = new LinearLayout(this);7. LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(8. ViewGroup.LayoutParams.WRAP_CONTENT,9. ViewGroup.LayoutParams.WRAP_CONTENT);10.// 将自定义的GameView添加到LinearLayout中11. layout.addView(gameview);
![](http://blog.51cto.com/attachment/201306/204202780.png)
流程一: mesarue()过程主要作用:为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性: mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。具体的调用链如下: ViewRoot根对象地属性mView(其类型一般为ViewGroup类型)调用measure()方法去计算View树的大小,回调View/ViewGroup对象的onMeasure()方法,该方法实现的功能如下: 1、设置本View视图的最终大小,该功能的实现通过调用setMeasuredDimension()方法去设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性:mMeasureWidth); 2 、如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。 2.1 对每个子视图的measure()过程,是通过调用父类ViewGroup.java类里的measureChildWithMargins()方法去实现,该方法内部只是简单地调用了View对象的measure()方法。(由于measureChildWithMargins()方法只是一个过渡层更简单的做法是直接调用View对象的measure()方法)。整个measure调用流程就是个树形的递归过程
流程二、 layout布局过程:主要作用 :为将整个根据子视图的大小以及布局参数将View树放到合适的位置上。具体的调用链如下: host.layout()开始View树的布局,继而回调给View/ViewGroup类中的layout()方法。具体流程如下: 1 、layout方法会设置该View视图位于父视图的坐标轴,即mLeft,mTop,mLeft,mBottom(调用setFrame()函数去实现)接下来回调onLayout()方法(如果该View是ViewGroup对象,需要实现该方法,对每个子视图进行布局) ; 2、如果该View是个ViewGroup类型,需要遍历每个子视图chiildView,调用该子视图的layout()方法去设置它的坐标值。
流程三、 draw()绘图过程由ViewRoot对象的performTraversals()方法调用draw()方法发起绘制该View树,值得注意的是每次发起绘图时,并不会重新绘制每个View树的视图,而只会重新绘制那些“需要重绘”的视图,View类内部变量包含了一个标志位DRAWN,当该视图需要重绘时,就会为该View添加该标志位。调用流程 : mView.draw()开始绘制,draw()方法实现的功能如下: 1 、绘制该View的背景 2 、为显示渐变框做一些准备操作(见5,大多数情况下,不需要改渐变框) 3、调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法) 4、调用dispatchDraw ()方法绘制子视图(如果该View类型不为ViewGroup,即不包含子视图,不需要重载该方法)值得说明的是,ViewGroup类已经为我们重写了dispatchDraw ()的功能实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能。 4.1dispatchDraw()方法内部会遍历每个子视图,调用drawChild()去重新回调每个子视图的draw()方法(注意,这个地方“需要重绘”的视图才会调用draw()方法)。值得说明的是,ViewGroup类已经为我们重写了dispatchDraw()的功能实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能。
二、如何自定义的View加入到布局中在解决了自定义View进行后绘图后,不知道怎么将这个View的实例添加到已经设定好的布局里,于是问了一下组长,找到了解决方法。举个实例:1.声明定义了一个LinearLayout的实例对象layout;2.声明定义了一个自定义View的实例对象view;3.使用layout.addView(view)就可以完成要求
4.GameView gameview =new GameView();5.// 定义了一个LinearLayout用来显示自定义的view6. LinearLayout layout = new LinearLayout(this);7. LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(8. ViewGroup.LayoutParams.WRAP_CONTENT,9. ViewGroup.LayoutParams.WRAP_CONTENT);10.// 将自定义的GameView添加到LinearLayout中11. layout.addView(gameview);
相关文章推荐
- 关于自定义View的一些总结
- Android关于自定义ViewGroup,onMeasure的一些实验结论。
- 学习自定义View之前你应该要知道的一些东西
- Android杂谈(8)关于自定义View的一些实践+遮罩理解
- android 自定义view所需要的一些东西
- 关于自定义view的一些问题
- 自定义View关于画圆弧的一些笔记
- 学习RecyclerView的一些东西
- 关于.net的一些基本的东西
- 关于线程中的一些原则行东西
- 关于域即上下文的理解而联想到的一些东西 一
- 自定义View时,用到Paint Canvas的一些温故,只有想不到没有做不到(实例 1,画一个简单的Activity并且实现他能实现的)
- 关于使用webview的一些记录
- 关于UITableView的Cell复用谈谈我的一些心得<滴水穿石>
- 自定义的view里面ondraw(canvas canvas)幕布上的东西怎么重新弄到imageview上面
- 关于自定义ViewGroup
- android 积累一些自定义view的知识
- 关于web构架的一些东西1
- 【随笔】关于函数的一些东西
- 有关于echarts的一些东西