小到控件布局,大到整個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見鬼去吧!