Android線性佈局重要屬性
上一節的例項中用到了兩個屬性gravity和layout_weight,這兩個屬性在Android開發中會經常用到,用法也比較複雜,下面我們來講解一下這兩個屬性的用法。
3.4.1 gravity屬性:
Android中的gravity屬性有兩種形式:layout_gravity和gravity,這兩種有什麼區別呢?從字面意思上就可以大概理解,第一個layout_gravity控制控制元件在父佈局中的位置(和margin比較類似),gravity可以控制控制元件中內容的顯示位置(和padding比較類似)。下面還會通過例項來比較一下這兩個屬性的效果。除了上面用到的屬性值center之外,還提供瞭如表3.3所示中常用屬性值供開發者呼叫(一次設定多個屬性值用 “|” 隔開):
表3.3 gravity屬性
首先我們看一下layout_gravity的用法(activity_main.xml):
<?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"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="center_horizontal" android:textSize="30dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:text="right" android:textSize="30dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:text="left" android:textSize="30dp" /> </LinearLayout>
設定了Linearlayout的orientation屬性值為vertical(垂直佈局),添加了三個TextView控制元件,並分別為這三個TextView添加了layout_gravity屬性,其值分別為:center_horizontal(水平居中)、right(居右)和left(居左),這時看一下預覽視窗中的顯示如圖3.18所示。
圖3.18 layout_gravity屬性示意
下面修改orientation屬性值為horizontal,然後看一下另外幾個屬性值的用法,修改activity_main.xml如下:
<?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="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="center_vertical" android:textSize="30dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="bottom" android:textSize="30dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" android:text="top" android:textSize="30dp" /> </LinearLayout>
這裡同樣添加了三個TextView並分別設定了其layout_gravity屬性值為:center_vertical(垂直居中)、bottom(底部)和top(頂部),這時檢視效果如圖3.19所示。
圖3.19 layout_gravity屬性示意二
可以看出,這時center_vertical將垂直居中,top將位於介面的頂部,bottom將位於介面的底部。
下面看一下gravity屬性的用法,如下:
<?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">
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="center_horizontal"
android:background="#41e67b"
android:gravity="center_horizontal|center_vertical"
android:text="center"
android:textSize="30dp" />
<TextView
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="left"
android:background="#355fa1"
android:gravity="right|bottom"
android:text="right|bottom"
android:textSize="30dp" />
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_gravity="right"
android:background="#afb639"
android:gravity="top|right"
android:text="top|right"
android:textSize="30dp" />
</LinearLayout>
為了演示方便,將各個TextView的寬和高都設定的足夠大併為每個TextView都添加了background屬性。第一個TextView添加了兩個gravity屬性值,中間用 “|” 符合隔開,這兩個屬性值(center_horizontal和center_vertical)和一個center是一樣的效果;第二個TextView為gravity添加了兩個屬性值right|bottom即右下角;第三個TextView設定gravity屬性值為top|right即右上角。檢視右側的預覽視窗,如圖3.20所示。
圖3.20 gravity屬性示意
3.4.2 layout_weight屬性:
layout_weight在分配螢幕的寬高上有很大的用處,它的用法很是靈活,結合不同的寬高值和weight值可以實現不同的效果和要求。
1. layout_width=“match_parent”
首先看一下設定寬為match_parent時,layout_weight不同值時的效果,程式碼如下:
<?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="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="5"
android:background="#cc5858"
android:text="layout_weight=5"
android:textSize="20dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#5baf54"
android:gravity="center_horizontal"
android:paddingBottom="15dp"
android:text="layout_weight=1"
android:textSize="20dp" />
</LinearLayout>
LinearLayout的orientation設定成了horizontal水平佈局,在LinearLayout中添加了兩個TextView並設定其寬的屬性為match_parent(若此時不新增layout_weight屬性,則第一個TextView將會覆蓋第二個TextView)。為第一個TextView設定了layout_weight屬性值為5,第二個TextView設定了layout_weight屬性值為1,這兩個值具體有什麼作用可以檢視預覽視窗,如圖3.21所示。
圖3.21 layout_weight屬性示意一
為了演示方便,這裡為TextView添加了background屬性,可以看出layout_weight為5時反而寬度很小,layout_weight為1時寬度很大,兩個TextView的比例基本上是1:5。
修改第一個TextView的layout_weight值為10,再次檢視如圖3.22所示。第一個TextView的寬被壓縮地更小了,將第一個TextView的layout_weight為100時,如圖3.23所示。
圖3.22 layout_weight屬性示意二
圖3.23 layout_weight屬性示意三
可以看出第一個TextView基本被壓縮地隱藏了。
2. layout_width=“wrap_content”
修改TextView的寬為wrap_content時再次看一下效果,修改程式碼如下:
<?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="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="5"
android:background="#cc5858"
android:text="layout_weight=5"
android:textSize="20dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#5baf54"
android:gravity="center_horizontal"
android:paddingBottom="15dp"
android:text="layout_weight=1"
android:textSize="20dp" />
</LinearLayout>
再次檢視預覽視窗如圖3.24所示,可以看出,和設定match_parent相反,設定為wrap_content時,layout_weight的值越大佔據的寬越大,但是並沒有按照5:1顯示,再次修改第一個TextView的layout_weight屬性值為10,預覽圖片如圖3.25所示。第一個TextView的寬僅僅增加了一點,第二個TextView仍然是一行包裹顯示,也就是說不管第一個TextView的layout_weight值有多大,第二個TextView都會包裹內容,不會被壓縮到消失。
圖3.24 layout_weight屬性示意四
圖3.25 layout_weight屬性示意五
3. layout_width=“0dp”
設定layout_width為0dp時才是正確的layout_weight屬性使用方法,因為SDK中對layout_weight的使用方法有如下解釋:
In order to improve the layout efficiency when you specify the weight, you should change the width of the EditText to be zero (0dp). Setting the width to zero improves layout performance because using "wrap_content"as the width requires the system to calculate a width that is ultimately irrelevant because the weight value requires another width calculation to fill the remaining space.
也就是說,在某個方向上使用layout_weight屬性推薦將這個方向上的width設定成0dp,系統將會採用另一套演算法來計算控制元件的控制元件佔比,這時layout_weight屬性值和佔據的“寬度”將是成正比例。
修改activity_layout.xml程式碼如下:
<?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="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="#cc5858"
android:padding="10dp"
android:text="layout_weight=2"
android:textSize="20dp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#5baf54"
android:gravity="center_horizontal"
android:padding="10dp"
android:text="layout_weight=1"
android:textSize="20dp" />
</LinearLayout>
因為佈局是水平佈局,所以其方向上的width就是layout_width,設定layout_width為0dp,檢視預覽視窗如圖3.26所示。
圖3.26 layout_weight屬性示意六
可以看出layout_weight為2的TextView所佔據的寬度是layout_weight為1的TextView所佔據寬度的兩倍,因此,推薦在開發時使用0dp。
3.4.3 weightSum屬性
上面講解了layout_weight屬性的使用,Android還提供了一個weightSum屬性供開發者呼叫。通過名字直觀分析,這個應該是所有layout_weight的和,此屬性將在父佈局中使用。
下面通過一個例項看一下weightSum的用法:
<?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"
android:weightSum="2">
<TextView
android:layout_width="0dp"
android:textSize="28dp"
android:gravity="center"
android:textColor="#ffffff"
android:background="#1d6e09"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Hello World!" />
</LinearLayout>
這個weightSum放在父佈局中並設定其值為“2”,這時可以認為整個寬為“2”,在子控制元件TextView中設定layout_weight為“1”並設定其layout_width為0dp,可以認為TextView佔據了整個寬的一半,如圖3.27所示。
圖3.27 weightSum屬性示意一
可以看出,TextView居中並佔據整個寬的一半。兩個控制元件時同樣也可以按照比例佔據螢幕寬的一半,修改程式碼如下:
<?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"
android:weightSum="6">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="#759c6c"
android:gravity="center"
android:text="2"
android:textColor="#ffffff"
android:textSize="28dp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#b33174"
android:gravity="center"
android:text="1"
android:textColor="#ffffff"
android:textSize="28dp" />
</LinearLayout>
設定父佈局的weightSum為“6”,將整個螢幕的寬分成6份,設定第一個TextView的layout_weight屬性值設為“2”,它將佔據2份螢幕的寬,將第二個TextView的layout_weight屬性值設為“1”,它將佔據1份螢幕的寬,檢視預覽視窗如圖3.28所示。
圖3.28 weightSum屬性示意二
可以看出,第一個TextView是第二個TextView的寬的兩倍,這兩個TextView佔據整個螢幕的一半。
如果你喜歡作者的文章,還可以購買他的書(京東自營):