视图的绘制过程 onMeasure()、onLayout()、dispatchDraw()

来源:互联网 发布:卡盟js代码申请 编辑:程序博客网 时间:2024/06/02 04:19

参考:Android的onMeasure和onLayout And MeasureSpec揭秘 

Android中自定义ViewGroup最重要的就是onMeasure和onLayout方法,都需要重写这两个方法,


ViewGourp可以包含很多个View,View就是它的孩子,比如LinearLayout布局是一个ViewGroup,在布局内可以放TextEdit、ImageView等等常用的控件,这些叫子View。


ViewGroup绘制 的过程是这样的:onMeasure → onLayout → DispatchDraw


onMeasure

onMeasure负责测量这个ViewGroup和子View的大小,onLayout负责设置子View的布局,DispatchDraw就是真正画上去了

其中:onMeasure继承自View,他是 获得ViewGroup和子View的宽和高


       @Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);int mWidth=getWidth();//这个方法是在View布局完成之后才有效,所以第一次调用的结果是0,int width = MeasureSpec.getSize(widthMeasureSpec);   //获取View宽度  和  getWidth方法相同        int height = MeasureSpec.getSize(heightMeasureSpec);      setMeasuredDimension(width/2, height);//设置View的宽高 这里有个问题             int childCount = getChildCount();   //获得子View的个数,下面遍历这些子View设置宽高                for (int i = 0; i < childCount; i++) {                  View child = getChildAt(i);                 child.measure(viewWidth, viewHeight);  //设置子View宽高              }  }

setMeasuredDimension//这个有个问题,我设置的是屏幕的1/2,但实际的结果是屏幕的1/4,onMeasure被多次执行了(应该是2次、或4次)

onLayout:

它才是设置子View的大小和位置。onMeasure只是获得宽高并且存储在它各自的View中,这时ViewGroup根本就不知道子View的大小,onLayout告诉ViewGroup,子View在它里面中的大小和应该放在哪里。注意两个的区别,我当时也被搞得一头雾水

@Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        int mTotalHeight = 0;           // 当然,也是遍历子View,每个都要告诉ViewGroup           int childCount = getChildCount();           for (int i = 0; i < childCount; i++) {            View childView = getChildAt(i);            // 获取在onMeasure中计算的视图尺寸            int measureHeight = childView.getMeasuredHeight();            int measuredWidth = childView.getMeasuredWidth();            childView.layout(left, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);     //这个ViewGroup应该是垂直分布           mTotalHeight += measureHeight;        }    }


ps: 在一个类初始化时,即在构造函数当中我们是得不到View的实际大小的。感兴趣的朋友可以试一下,getWidth()和getMeasuredWidth()得到的结果都是0.但是我们可以从onDraw()方法里面的到控件的大小。


0 0
原创粉丝点击