在Android中對控件布局指定尺寸時,一般有兩種方式:一種設定為自適應布局,即match_parent(fill_parent)或者wrap_content,通過根據父布局大小或者自己內容來產生一個動態尺寸;另外一種通過指定一個具體數值的方式定義成固定布局,單位可以是px/dp/sp等。這在絕大數情況下是可以解決問題的。
可是有沒有辦法像div+css里那樣根據屏幕的尺寸,對控件布局進行“百分比”設定呢?這時就需要用到LinearLayout和他的子控件屬性layout_weight。“layout_”前綴告訴我們此屬性依賴於他的父布局。LinearLayout(線性布局)我們知道主要是讓他的子控件實現並排或者並列的布局效果,一般子控件的大小是根據自身內容或者一個具體數值尺寸。而layout_weight(權重)屬性則是表示當前控件在他的父布局的“剩余空間”中所占的比重(或者叫“比例”、“百分比”)。初看這段話可能不太好理解,我們看例子。
1.layout_weight值
我們希望下面兩個按鈕各占屏幕的一半:
![]() |
![]() |
豎屏效果 | 橫屏效果 |
那么只需要把兩個按鈕“layout_weight”值設成相等值(比如:1),並且把“layout_width”設成“0dp”,如下代碼:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <Button
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="A"
- android:background="#fdb6b6"/>
- <Button
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="B"
- android:background="#b6d5fd"/>
- </LinearLayout>
我們把LinearLayout的總空間(其實應該叫“剩余空間”,我們下面再說)看作100%,那么設定了“layout_weight”值的總和就代表100%。這里有兩個控件設置了layout_weight(分別為1),所以值2就相當於100%空間。而按鈕設定的值1就相當於 1 / 2 = 50%,代表當前控件占總空間的50%。因為LinearLayout的layout_width=“match_parent”,所以就相當於屏幕的50%。
既然如此,那么layout_weight具體是什么數值無所謂了,只要保證兩個按鈕的值相等就能實現各占50%了,我們把兩個按鈕的layout_weight同時設成“0.5”或者“2”看看,驗證我們的推想。那么可不可以把layout_weight同時設成“0”?當然不行!layout_weight默認就是0,表示權重不起作用,控件依賴具體的layout_width或者layout_height起作用。
還有另一個問題,“layout_width”一定要設成“0dp”嗎?一定要!,具體為什么,第四部分專門介紹。現在只要知道,如果我們平行百分比分割屏幕就要把“layout_width”設成“0dp”,而需要垂直百分比分割就把“layout_height”設成“0dp”。
2.weightSum值
如果我們只有一個按鈕,希望占屏幕的50%並且在中間,如下面的效果:
![]() |
![]() |
豎屏效果 | 橫屏效果 |
我們只有一個控件可以設置layout_weight屬性,而不管我們設多少,他都代表100%。這時父布局(LinearLayout)中的weightSum屬性就可以大顯身手了。weightSum的值就代表父布局的100%總空間,這是我們把LinearLayout的“weightSum”屬性設置為“1”,按鈕的“layout_weight”設置為“0.5”:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:gravity="center"
- android:weightSum="1">
- <Button
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="0.5"
- android:text="A"
- android:background="#fdb6b6"/>
- </LinearLayout>
其實weightSum一直存在,只是我們不設置時,默認為所有子控件“layout_weight”值的總和,就像第一部分介紹的樣子。
3.剩余空間
前面我們提到layout_weight其實分割的是父空間的“剩余空間”,那么具體指的是哪部分空間呢?我們看個例子:
最右邊的按鈕的空間大小是根據其內容設置的,而左邊的兩個按鈕則各占剩下空間的50%,這里的剩下空間就是我們一直說的“剩余空間”。在LinearLayout布局中首先把layout_weight=0(即沒有設置layout_weight屬性)的控件所占的空間去掉(這部分控件已經通過具體的layout_width和layout_height值指定了空間大小),再將剩下的空間交給設定了layout_weight值的控件按比百分比進行分割。而在前面兩個例子中,因為全是設定了layout_weight的控件,所以“剩余空間”正好等於父布局的總空間了。本例的代碼:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <Button
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="A"
- android:background="#fdb6b6"/>
- <Button
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="B"
- android:background="#b6d5fd"/>
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="CCCC"
- android:background="#b6fdc5"/>
- </LinearLayout>
4.layout_width或layout_height的值
第一部分介紹到如果需要通過layout_weight來設置控件尺寸,一定要把layout_width或layout_height的值設定為“0dp”。那如果不這樣做會怎樣?我們先看第一個例子代碼:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="A"
- android:background="#fdb6b6"/>
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="B"
- android:background="#b6d5fd"/>
- </LinearLayout>
將其中的layout_width設置成“wrap_content ”,看看運行效果:
如像設置了也沒有影響啊,我們將右邊的控件文字設長一點,再看看效果:
這時發現右邊的控件被文字內容撐寬了,而不是我們希望的各50%,而如果將layout_width仍然改為“0dp”,則一切正常:
我們再看第二個例子,有三個按鈕控件,其中A按鈕占 50%,B和C按鈕分別占25%,如下圖:
如果我們把這三個按鈕的layout_width屬性都設成“math_parent”:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <Button
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="2"
- android:text="A"
- android:background="#fdb6b6"/>
- <Button
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="B"
- android:background="#b6d5fd"/>
- <Button
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="C"
- android:background="#b6fdc5"/>
- </LinearLayout>
會是什么效果呢?