自定义布局机制

来源:互联网 发布:如何提高淘宝等级 编辑:程序博客网 时间:2024/05/16 13:37

公司项目中有一个控件自动换行需求,也就是从在ViewGroup中布局子View时根据view的大小,自动换行,根据这个需求,我开始研究android布局的源码,android控件布局需要执行三个过程,onMeasure()、
onLayout()、onDraw();
1、每个布局过程中onMeasure(int widthMeasureSpec, int heightMeasureSpec)会接收两个参数,View调用此方法来确定本身和所包含内容的大小。传入的参数是 受上一层大小影响下的对水平空间和垂直空间的要求,我们可以调用
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);//获得传递给本层的上层宽度模式
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);//获得上层传递给本层的允许宽度

而布局的模式包括EXACTLY(精确模式)、UNSPECIFIED(不确定模式)、AT_MOST(至多模式)也就是说根据上一层要求,本层宽度高度的适配形式。根据传递参数的要求,本层布局可以设置本层布局的宽度高度模式及宽度高度值,传递给下一层view的measure方法中,然后通过setMeasuredDimension(width, height);这个方法就是我们重写onMeasure()所要实现的最终目的。它的作用就是存储我们测量好的宽高值。
2、onLayout()决定View在ViewGroup中的位置,上面已经说完了测量过程,这个阶段开始讲子view在本层的布局,onLayout(boolean changed, int l, int t, int r, int b)
其中
1)changed代表view有新的尺寸或位置;
2)l代表本层相对于父view的Left位置;
3)t代表本层相对于父view的Top位置;
4)r代表本层相对于父view的Right位置;
5)b代表本层相对于父view的Bottom位置。
通过该过程,循环遍历子view 调用child.layout()完成本层对子view的布局
参考代码:

 protected void onLayout(boolean changed, int l, int t, int r, int b) {               int mTotalHeight = 0;                 int childCount = getChildCount();          for (int i = 0; i < childCount; i++) {              View childView = getChildAt(i);                         int measureHeight = childView.getMeasuredHeight();              int measuredWidth = childView.getMeasuredWidth();                childView.layout(l, mTotalHeight, measuredWidth, mTotalHeight                      + measureHeight);              mTotalHeight += measureHeight;          }      }  

3、onDraw()一般不用我们自己去重写,我们只要写好前两个过程就够了## 标题 ##

0 0
原创粉丝点击