RelativeLayout源码解析

RelativeLayout源码解析

参考博客:

http://blog.csdn.net/wz249863091/article/details/51757069

RelativeLayout在measure的时候每次都一定会遍历2次,性能有所降低,在实际使用的时候,尽量减少布局嵌套层数


RelativeLayout作为一个ViewGroup的子类,主要起到的是一个容器的作用,所以在RelativeLayout源码中没有重载onDraw的方法又由于RelativeLayout内部的子view都是以相对关系存在的,所以只要计算出子view的坐标,就能知道每个子view该放在布局哪

在RelativeLayout的measure过程中,主要可以分为6个步骤

1.先把内部子view根据纵向关系和横向关系排序

2.初始化一些变量值

3.遍历水平关系的view

4.遍历竖直关系的view

5.baseline计算

6.宽度和高度修正个位置

基本概念

纵向关系:marginTop、marginBottom…

ABOVE, BELOW, ALIGN_BASELINE, ALIGN_TOP, ALIGN_BOTTOM

水平关系:marginLeft、marginRight…

LEFT_OF, RIGHT_OF, ALIGN_LEFT, ALIGN_RIGHT, START_OF, END_OF, ALIGN_START, ALIGN_END

dependents:依赖别人的;eg:a,b依赖c,那么c的dependents中存的是a,b

dependencies:被依赖的

onMeasure过程

DependencyGraph

sortChildren: 这个方法也很简单主要对左右关系和上下关系的view数组进行非空判断,然后用DependencyGraph 来完成排序,DependencyGraph 顾名思义,就是关系图的意思

add(): 有图就有节点,根据view生成一个节点,如果是一个有效id就把节点加到List当中

getSortedViews:排序算法

findRoots:找到不依赖别的view的view,作为root节点

初始化一些变量值

确定一下宽高

遍历水平关系的View

根据方向获得子view中设置的规则:int[] rules = params.getRules(layoutDirection);

把这些左右方向的规则转化成左右坐标:applyHorizontalSizeRules(params, myWidth, rules);

然后测算出水平方向的子view尺寸: measureChildHorizontal(child, params, myWidth, myHeight);

确定水平方向子view位置: if (positionChildHorizontal(child, params, myWidth, isWrapContentWidth)) {
offsetHorizontalAxis = true;
}

遍历垂直关系的View
计算baseline
宽度和高度修正

这部分代码比较好理解,在onMeasure()之前就提到
这里谷歌工程师也告诉我们了
在计算子分配子view的坐标时候,需要用到父view的尺寸
但是在完成下面这个操作之前,我们是无法拿到一个准确值
所以我们先用一个默认值代替
在计算完之后,我们再用偏移量去更新真实坐标
偏移量的计算公式是offset = DEFAULT_WIDTH - width
这里就是拿到准确的宽度和高度之后,对一些依赖父容器决定位置的子view重新做一次测量
然后根据gravity对偏移量再一次修正
然后如果是右到左显示,再做一次修改
整个onMeasure()过程就结束了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值