原文:http://blog.csdn.net/a396901990/article/details/38129669
一、简介
在自定义view的时候,其实很简单,只需要知道3步骤:
1.测量——onMeasure():决定View的大小,关于此请阅读《Android自定义控件之onMeasure》
2.布局——onLayout():决定View在ViewGroup中的位置
3.绘制——onDraw():如何绘制这个View。
这篇文章主要来谈谈第二步布局(Layout)
二、View视图结构
View视图可以是单一的一个如TextView,也可以是一个视图组(ViewGroup)如LinearLayout。
如图:对于多View的视图他的结构是树形结构,最顶层是ViewGroup,ViewGroup下可能有多个ViewGroup或View。
这个树的概念很重要,因为无论我们是在测量大小或是调整布局的时候都是从树的顶端开始一层一层,一个分支一个分支的进行(树形递归)。
三、onLayout函数
measure的作用就是为整个View树计算实际的大小,而通过刚才对View树的介绍知道,想计算整个View树的大小,就需要递归的去计算每一个子视图的大小(Layout同理)。
对每一个视图通过onMeasure方法的一系列测量流程后计算出实际的高(mMeasuredHeight)和宽(mMeasureWidth)传入setMeasuredDimension()方法完成单个View的测量,如果所测的视图是ViewGroup则可以通过measureChild方法递归的计算其中的每一个子view。对于每个View的实际宽高都是由父视图和本身视图决定的。
Layout的作用就是为整个View树计算实际的位置,而通过刚才对View树的介绍知道,想计算整个View树的位置,就需要递归的去计算每一个子视图的位置(Measure同理)。
而确定这个位置很简单,只需要mLeft,mTop,mRight,mBottom四个值(注意:这4个值是子View相对于父View的值,下面会详细介绍)。
在代码中如何设置这4个值呢?
首先,无论是系统提供的LinearLayout还是我们自定义的View视图,他都需要继承自ViewGroup类,之后必须要做的就是重写onLayout方法(因为在onLayout在ViewGroup中被定义为抽象方法)。
ViewGroup的onlayout:
- @Override
- protected abstract void onLayout(boolean changed, int l, int t, int r, int b);
View.java的onLayout:
- /**
- * 当这个view和其子view被分配一个大小和位置时,被layout调用。
- * @param changed 当前View的大小和位置改变了
- * @param left 左部位置(相对于父视图)
- * @param top 顶部位置(相对于父视图)