android5.1 RelativeLayout源码浅析

5.3         RelativeLayout

 

5.3.1         介绍

RelativeLayout是android的5大常用布局之一,其使用方法和常用介绍这里不再赘述。

 

我们对RelativeLayout一般了解的是它是一个布局,这里从类的角度和view的角度来分析它。

 

RelativeLayout是一个类,所以有其构造过程,在布局文件被inflate的时候,会去创建这个类。

 

RelativeLayout extends ViewGroup,所以它是view的子类和实例,在RelativeLayout 类型的view的绘制流程中,实际会调用到RelativeLayout的方法。

 

除此之外,RelativeLayout并无其他特殊,其布局文件的属性也就类似我们调用一般类的方法设置成员变量一样。

 

android:layout_above

Positions the bottom edge of this view above the given anchor view ID. 

android:layout_alignBaseline

Positions the baseline of this view on the baseline of the given anchor view ID. 

android:layout_alignBottom

Makes the bottom edge of this view match the bottom edge of the given anchor view ID. 

android:layout_alignEnd

Makes the end edge of this view match the end edge of the given anchor view ID. 

android:layout_alignLeft

Makes the left edge of this view match the left edge of the given anchor view ID. 

android:layout_alignParentBottom

If true, makes the bottom edge of this view match the bottom edge of the parent. 

android:layout_alignParentEnd

If true, makes the end edge of this view match the end edge of the parent. 

android:layout_alignParentLeft

If true, makes the left edge of this view match the left edge of the parent. 

android:layout_alignParentRight

If true, makes the right edge of this view match the right edge of the parent. 

android:layout_alignParentStart

If true, makes the start edge of this view match the start edge of the parent. 

android:layout_alignParentTop

If true, makes the top edge of this view match the top edge of the parent. 

android:layout_alignRight

Makes the right edge of this view match the right edge of the given anchor view ID. 

android:layout_alignStart

Makes the start edge of this view match the start edge of the given anchor view ID. 

android:layout_alignTop

Makes the top edge of this view match the top edge of the given anchor view ID. 

android:layout_alignWithParentIfMissing

If set to true, the parent will be used as the anchor when the anchor cannot be be found for layout_toLeftOf, layout_toRightOf, etc. 

android:layout_below

Positions the top edge of this view below the given anchor view ID. 

android:layout_centerHorizontal

If true, centers this child horizontally within its parent. 

android:layout_centerInParent

If true, centers this child horizontally and vertically within its parent. 

android:layout_centerVertical

If true, centers this child vertically within its parent. 

android:layout_toEndOf

Positions the start edge of this view to the end of the given anchor view ID. 

android:layout_toLeftOf

Positions the right edge of this view to the left of the given anchor view ID. 

android:layout_toRightOf

Positions the left edge of this view to the right of the given anchor view ID. 

android:layout_toStartOf

Positions the end edge of this view to the start of the given anchor view ID.  



5.3.2         绘制分析

RelativeLayout继承自ViewGroup,属于view控件,因此也遵从view的绘制逻辑。

 

根据我们对view的理解,其绘制大体也是按measure—layout—draw的流程处理的。

 

 

5.3.2.1                            Measure过程

 

RelativeLayout的测量过程分如下几大步,

 

5.3.2.1.1子view的分组排序

调用sortChildren();,将子view排序上水平方向和垂直方向两个view列表:mSortedHorizontalChildren、mSortedVerticalChildren。

 

sortChildren

将子view排序上水平方向和垂直方向两个view列表。

findRoots

找出不依赖别的view的view,布局里view间的关系有自己独立的,有依赖于其他的view的。这个函数将view做成内存节点,并将view的属性读出来,设置他们相互的关系是否依赖和被依赖,并将不依赖的view做成一个列表返回。

getSortedViews

将所有view按过滤规则排序,这里的过滤规则主要分两个大方向:水平和垂直。其排序思路如下,以水平为例(便于理解,我们自己定义被依赖者为“上级”,依赖其他view的为“下级”,一个上级有多个下级,一个下级也可以有多个上级,但上级是没有上级的,在排序到新view列表中时,同级view之间按扫描顺序添加到列表,下级view则添加到其最后一个上级之后),先是用findRoots找出一个水平方向独立不依赖的上级view列表,先将上级view逐个添加到排序列表,每添加一个上级view时,找到其下级view,将他们的关系从下级view里面删除,如果下级view由于这个原因变成独立不依赖的“假上级”view,则可以将它加入上级view列表,在下一个循环就被加入到排序列表,位于其以前的上级view之后;如果下级view有多个上级view,则会在上级view列表轮询的时候,加入到最后一个上级view之后,最终形成这样一个排序列表(上级a--下级a--上级b-下级b1-下级b2-下级ab-上级c--下级c--下级ac--下级abc,下标表示下级的依赖关系)。另需注意的是将可见不可见的view都排列起来的,因为可见不可见随时会改变,保持所有view的关系是必须的。

 

 

5.3.2.1.2坐标和属性初始

初步初始四个方向坐标,初始坐标模式,初始gravity。

 

传入的widthMeasureSpec是一个32位整数,是坐标模式和坐标值的组合数据,坐标模式占高2bit,含义如下:

 

        /**

         * Measure specification mode: The parent has not imposed any constraint

         * on the child. It can be whatever size it wants.

         */

        public static final int UNSPECIFIED = 0 << MODE_SHIFT;

 

        /**

         * Measure specification mode: The parent has determined an exact size

         * for the child. The child is going to be given those bounds regardless

         * of how big it wants to be.

         */

        public static final int EXACTLY     = 1 << MODE_SHIFT;

 

        /**

         * Measure specification mode: The child can be as large as it wants up

         * to the specified size.

         */

        public static final int AT_MOST     = 2 << MODE_SHIFT;

 

 

5.3.2.1.3水平方向

水平方向的子view测量是计算出所有view的水平方向的坐标值,调用3个函数,

 

applyHorizontalSizeRules

根据view的可见性和相互关系,初步算出每个view的左右坐标。相互关系以被依赖者为锚点,根据getSortedViews,总有一个上级不依赖于其他view,只依赖于父view,作为基准锚点的。

measureChildHorizontal

单个view的独立坐标测量

positionChildHorizontal

精确计算出每个view左右坐标值

 

 

5.3.2.1.4垂直方向

垂直方向和水平方向处理逻辑类似。

 

但多一个步骤,就是根据wrapcontent和gravity初步计算relativeLayout的坐标。

 

 

5.3.2.1.5 RelativeLayout坐标计算

根据wrapcontent和gravity等属性值精确计算relativeLayout的坐标。

 

 

5.3.2.2                            Layout过程

其layout过程就是遍历所有子view的layout

 

 

 

5.3.2.3                            Draw过程

没有重载draw方法,就是直接使用了父类的draw方法。

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值