小到控件布局,大到整个app的屏幕适配,百分比布局都是很重要的。可惜、可恨的是android的百分比布局先天支持的不太好。举个例子,如果说要使两个按钮按照1:2铺满父容器,该怎么办,这个大家会说,很容易啊:
(1) 先把按钮都放进LinearLayout容器。
(2) 修改按钮的layout_weight,分别赋值为1和2。
正如所说,效果还不错!
但是如果按钮的内容太多了,就不行了。
原来,layout_weight的意思是在布局(没有layout_weight)后,把剩余空间按照比例再次分配给控件,并不是真的百分比布局。OK,忍忍吧,把按钮的layout_width直接设置为0,不就行了。的确,搞定。
但是,如果两个按钮不是很规矩,按钮2顶部偏要和按钮1的底部对齐(有各种设计需求,大家懂得),该怎么办?
还可以继续忍:创建两个LinearLayout容器,一个在上,一个在下,把按钮1放在上面的LinearLayout,后面加入Space, 设置 layout_weight,分别为1和2。在下面的LinearLayout容器中,先加入Space,layout_weight设置为1,最后放入按钮2,layout_weight设置为2。复杂是复杂了点,不过也算OK。代码如下:
<?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:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="0dp" android:padding="0dp"> <Button android:id="@+id/button1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button 1" android:layout_weight="1"/> <Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" /> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <Space android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/button2" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Button 2" android:layout_weight="2"/> </LinearLayout> </LinearLayout>
接着看下面的,这个怎么办?
按钮1和按钮2的宽度比例仍然是1:2,但是按钮1是右挨着中间位置,两个按钮左对齐。
不容置疑,大家还是有各种办法的。但是,我是受不了,不能再忍了!layout_weight, 去你的!那不用layout_weight,该怎么办呢?先看代码:
<?xml version="1.0" encoding="utf-8"?> <com.lanbitou.components.TagRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 1 " android:tag="l:50w%p-100w%;w:33w%p"/> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button 2" android:tag="l:100l%button1;w:67w%p"/> </com.lanbitou.components.TagRelativeLayout>
更复杂的布局,但是代码很简洁,是不是?怎么办到的?就如大家看到了,我引入了一个新布局器TagRelativeLayout。它支持在视图tag里面用简单的表达式来定义位置和大小属性。水平位置、垂直位置、宽度、高度属性分别用l、t、w、h表示,也就是left、top、width、height的首字母。属性和值作为一个属性对,用冒号分开。属性值可以是绝对值,比如: 20,单位不用写,默认是dp;也可以是百分比,比如上面例子中的按钮1,它的宽度是这样指定的:33w%p。是什么意思呢?%前面的字母(w、h、l、t)代表相对视图的属性,数字就是百分比例。%后面代表的是相对视图的id,有两种特殊情况:如果没有写id就是相对于自己,p代表父视图。所以w:33w%p的意思就是按钮1的宽度是父视图宽度的33%。
此外,属性值支持加减运算。比如上面按钮1的水平位置是这样指定的: l:50w%p-100w%。首先,我们来分解下,50w%p代表父亲宽度的一半,也就是水平中间位置;100w%就是自己的宽度。连起来就是水平中间位置减去自身的宽度。换句话说,按钮1右对齐水平中央位置。
现在来看看一些表达式的例子。
水平、垂直居中:
android:tag="l:50w%p-50w%;t:50h%p-50h%"
上图:
等宽:
android:tag="t:100t%button1+100h%button1;w:100w%button1" //按钮2的tag,主要看w的属性值
效果是这样的:
垂直居中:
android:tag="l:60w%p;t:100t%button1+50h%button1-50h%"//按钮2的tag,主要看t的属性值
更多的?留给大家写吧。
TagRelativeLayout布局简单、灵活。再也不需要为了布局,构建复杂的视图层次了,一个TagRelativeLayout全部搞定,让RelativeLayout和LinearLayout见鬼去吧!
跟layout_weight说88,轻松搞定百分比布局