android 自定义控件之ViewGroup生命周期执行步骤

万事须己运,他得非我贤。这篇文章主要讲述android 自定义控件之ViewGroup生命周期执行步骤相关的知识,希望能为你提供帮助。
前言
了解ViewGroup的生命周期的执行步骤对于自己自定义ViewGroup的时候十分重要,清楚了整个流程才能对ViewGroup有更深的理解。本文从个人的总结,来阐述一下执行的顺序。

执行说明
首先ViewGroup的常用的生命周期主要有:构造方法、onLayout()、onFinishInflate()、onMeasure()、onSizeChanged(),前两种在创建ViewGroup子类的时候,必须重写。至于draw()和drawChild()是其用来绘制背景和子View用的,就不在生命周期里一一叙述。

第一种:在xml里直接引用的,执行顺序一般是:构造方法-> onFinishInflate()(只执行一次)-> onMeasure()(可能多次执行)-> onSizeChanged()(在重新onMeasure的时候发现跟之前测量的尺寸不一样的时候就会回调此方法)-> onLayout()(布置子View)-> onMeasure()-> onLayout().......
 
第二种:在Activity中setContentView( newCustomView(this))引用的,执行顺序与第一种相比,除了构造方法引用的不一致和不执行onFinishInflate()外,其他基本一致。
 
第三种:在Activity中直接new CustomView(this)而且不添加任何父布局的时候只会执行构造方法,其它不会执行。

总结技巧:
onMeasure()里一般是定义子控件的测量尺寸和宽高。
首先设置ViewGroup自身的尺寸如下:

int  widthSize  =  MeasureSpec.getSize(widthMeasureSpec);     int  heightSize  =  MeasureSpec.getSize(heightMeasureSpec);     setMeasuredDimension(widthSize,  heightSize);

然后设置子View的尺寸例如下面:
View  leftMenuView  =  getChildAt(1);     MarginLayoutParams  lp  =  (MarginLayoutParams)                                    leftMenuView.getLayoutParams();     final  int  drawerWidthSpec  =  getChildMeasureSpec(widthMeasureSpec,                                    mMinDrawerMargin  +  lp.leftMargin  +  lp.rightMargin,                                    lp.width);     final  int  drawerHeightSpec  =  getChildMeasureSpec(heightMeasureSpec,                                    lp.topMargin  +  lp.bottomMargin,                                    lp.height);     leftMenuView.measure(drawerWidthSpec,  drawerHeightSpec);         View  contentView  =  getChildAt(0);     lp  =  (MarginLayoutParams)  contentView.getLayoutParams();     final  int  contentWidthSpec  =  MeasureSpec.makeMeasureSpec(                                    widthSize  -  lp.leftMargin  -  lp.rightMargin,  MeasureSpec.EXACTLY);     final  int  contentHeightSpec  =  MeasureSpec.makeMeasureSpec(                                    heightSize  -  lp.topMargin  -  lp.bottomMargin,  MeasureSpec.EXACTLY);     contentView.measure(contentWidthSpec,  contentHeightSpec);

int getChildMeasureSpec(int spec,int padding,int childDimension) 返回的是测量尺寸规格spec,可以给子View设置padding,不需要设置padding就直接如contentView一样。
onLayout()布局子view的位置,基本上用到layout(left,top,right,bottom);

getWidth()和getMeasureWidth()的区别与联系:
getMeasuredWidth(): 只要一执行完 setMeasuredDimension() 方法,就有值了,并且不再改变。简单来说执行完onMeasure里的方法后就可以获取;
getWidth()只有在执行onMeasure()之后才能获取,但是可能应为布局大小调整发生变化,如果onLayout()没有对子View的宽高进行修改,那么两个值相等。
 
生命周期表:
android 自定义控件之ViewGroup生命周期执行步骤

文章图片

 
参考:http://blog.csdn.net/anydrew/article/details/50985763
【android 自定义控件之ViewGroup生命周期执行步骤】 




















    推荐阅读