android:layout_weight属性是控制LinearLayout如何进行子组件的布置安排。常称为“权重”。在实际开发中比较常用,但是很多开发者可能并不知道weightlayout的工作原理,或者只会一种使用方式,那就是只会设置N个组件占用相同的宽度或高度。
今天天我们就对这个属性工作原理进行讲解,了解其原理之后,你就可以随心所欲的控制你的布局了。
LinearLayout是分为两个步骤来设置视图的宽度或者高度的。
第一步:LinearLayout查看layout_width属性值(竖直方位则查看layout_height属性值)。如果为wrap_content则它们获得的空间大小仅够绘制自身,如果是match_parent则是父控件的全部空间。
注:
1)fill_parent设置一个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间。设置一个顶部布局或控件为fill_parent将强制性让它布满整个屏幕。
2)match_parent Android2.2中match_parent和fill_parent是一个意思 .两个参数意思一样,match_parent更贴切,于是从2.2开始两个词都可以用。那么如果考虑低版本的使用情况你就需要用fill_parent了。
第二步:LinearLayout依据layout_weight属性值进行额外的空间分配。这个值是一个容器中所有layout_weight属性值相加,这里记作SUM,然后每个设置layout_weight的组件额外获得的空间则为,当前组件的layout_weight的值 / SUM * 剩余空间。
最终组件的宽度或者高度就是上面两步的和。
下面我们实际操作一下,根据实际的例子来体会一下。
通常情况下使用android:layout_weight会分为三种情况:
1. layout_width=”0dp”
2. layout_width=”match_parent”
3. layout_width=”warp_content”
layout_height原理与layout_width一样。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="horizontal">
<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@android:color/holo_red_dark" android:gravity="center" android:text="1" android:textColor="@android:color/white" />
<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:background="@android:color/holo_blue_dark" android:gravity="center" android:text="2" android:textColor="@android:color/white" />
<TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" android:background="@android:color/black" android:gravity="center" android:text="3" android:textColor="@android:color/white" />
</LinearLayout>
效果图为:
从代码中看出三个TextView的layout_weight的属性值分别为1、2、2,那么我们根据上面的理论来分析一下。
第一步:layout_width=”0dp”. 所以额外剩下的空间则为父组件的宽度。
第二步:
额外空间计算:
- 第一个TextView: 0 + 1 / (1 + 2 + 2) * parent_width= 1/5 * parent_width
- 第一个TextView: 0 + 2 / (1 + 2 + 2) * parent_width = 2/5 * parent_width
- 第一个TextView: 0 + 2 / (1 + 2 + 2) * parent_width = 2/5 * parent_width
这个结果也符合我们上面的效果图。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="horizontal">
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@android:color/holo_red_dark" android:gravity="center" android:text="1" android:textColor="@android:color/white" />
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2" android:background="@android:color/holo_blue_dark" android:gravity="center" android:text="2" android:textColor="@android:color/white" />
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2" android:background="@android:color/black" android:gravity="center" android:text="3" android:textColor="@android:color/white" />
</LinearLayout>
上面代码我们将layout_width设置为match_parent,比例未变,效果如下:
从效果图上来看权重值小的反而占用空间变大了,这是为什么呢?不要慌张!按照上面的步骤算一遍,看看结果:
第一步:layout_width=”match_parent”即父组件的宽度(1 * parent_width),一共有三个TextView,则总的宽度就是3 * parent_width,那么额外的空间就是:
1 * parent_width - 3 * parent_width = -2 * parent_width
第二步:
额外空间计算:
- 第一个TextView:1 * parent_width + (1 / (1 + 2 + 2) * -2 * parent_width) = 3/5 * parent_width
- 第一个TextView: 1 * parent_width + (2 / (1 + 2 + 2) * -2 * parent_width) = 1/5 * parent_width
- 第一个TextView: 1 * parent_width + (2 / (1 + 2 + 2) * -2 * parent_width )= 1/5 * parent_width
怎么样,计算的结果与现实的效果非常吻合。我们再来看看最后一种可能。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="horizontal">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:background="@android:color/holo_red_dark" android:gravity="center" android:text="1" android:textColor="@android:color/white" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="2" android:background="@android:color/holo_blue_dark" android:gravity="center" android:text="2" android:textColor="@android:color/white" />
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="2" android:background="@android:color/black" android:gravity="center" android:text="3" android:textColor="@android:color/white" />
</LinearLayout>
上面的代码我们同样的只是修改了layout_width=”wrap_content”,权重未变化。效果图如下:
从效果上可能与第一种情况差不多,不急,我们还是通过上面的方法进行验证:
第一步:layout_width=”wrap_content”即为组件本身的宽度,这里记作child_width。那么额外的控件则为parent_width - (3 * child_width)。
第二步:
额外空间计算:
- 第一个TextView: child_width + 1 / (1 + 2 + 2) * (parent_width - (3 * child_width))= 1/5 * parent_width + 2/5 * child_width
- 第一个TextView: child_width + 2 / (1 + 2 + 2) * (parent_width - (3 * child_width)) = 2/5 * parent_width - 1/5 * child_width
- 第一个TextView: child_width + 2 / (1 + 2 + 2) * (parent_width - (3 * child_width)) = 2/5 * parent_width - 1/5 * child_width
貌似结果也不是很直观,其实这里我们还有第四种情况,那就是组件的layout_width不是上面的三种框,而是一个大于0dp的具体数值,例如layout_width=”50dp”,那么上面的child_width则为50,我们替换后得到的结果如下:
1/5 * parent_width + 20
2/5 * parent_width - 10
2/5 * parent_width - 10
从结算结果和效果图的对比上来看,结果应该是对的。自信点!
怎么样,通过上面的讲解与分析,相信你对android:layout_weight这个属性一定新的认识了。赶快验证一下吧,如果有什么描述错误地方欢迎大家指正。