如果你學過html,用div+css里根據屏幕的尺寸,對控件佈局進行“百分比”設定是非常舒服的也非常好用,然而在Android中對控件佈局指定尺寸時卻無法直接使用百分比,初入android時覺得缺少這個非常差勁。
在Android中對控件佈局指定尺寸時,一般有兩種方式:
一、 一種設定爲自適應佈局,即match_parent(fill_parent)或者wrap_content,通過根據父佈局大小或者自己內容來產生一個動態尺寸;
二、 另外一種通過指定一個具體數值的方式定義成固定佈局,單位可以是px/dp/sp等。
那麼在android中如果想像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>
會是什麼效果呢?
這裏layout_weight設置成2的A按鈕反而沒有了!什麼原因,我們分析一下:
首先,佈局需要計算“剩餘空間”,因爲ABC三個按鈕控件都設置了math_parent的寬度,所以“剩餘空間”變成了:
(這裏糾正一下第三部分“剩餘空間”描述,不是去除layout_weight=0的控件,而是明確設置了寬高的值的控件的空間。)
下面計算A按鈕所佔空間:
B按鈕所佔空間 = 100%父空間 + (-2 * 100%父空間) * 25% = 50%
C按鈕和B按鈕一樣。所以如果我們給width或height設置了值,而layout_weight所產生的效果就不一定是我們想要的了。
以上是對layout_weight屬性的總結,希望對大家有所幫助。如果有理解錯誤的地方,歡迎大家幫忙指正,這裏先謝謝了。