頁面的五種佈局以及巢狀『Android系列八』
因為學習比較晚,我用的相關版本為SDK4.1、eclipse4.2,而自己看的教材都是低版本的,這造成了細節上的不同,有時候給學習造成了不小的困擾,不過這樣也好,通過解決問題獲得的知識理解更加深刻一點,這篇文章就是因為版本不同這個原因由來的。
使用上面說的版本新建一個Android專案,然後開啟main.xml檔案,注意看程式碼:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="@string/hello_world" tools:context=".Main" /> </RelativeLayout>
RelativeLayout,這個就是五種佈局的其中之一,而大多數教材上面講的都是LinearLayout佈局,佈局的不同造成模擬機介面顯示的不同,為了避免再次困然,先把五種佈局都瞭解一下吧。
五個佈局物件:RelativeLayout、LinearLayout、TableLayout、FrameLayout、AbsoulteLayout。
佈局一:
相對佈局RelativeLayout,定義各控制元件之間的相對位置關係,通過位置屬性和各自的ID配合指定位置關係,在指定位置關係時引用的ID必須在引用之前先被定義,否則將出現異常。
layout/main.xml的程式碼
定義了4個文字標籤,各自的文字值(下面幾種佈局使用同樣的strings.xml檔案)<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/firstText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FFFFFF" android:text="@string/first" /> <TextView android:id="@+id/secondText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FFFF00" android:text="@string/second" /> <TextView android:id="@+id/thirdText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FF00FF" android:text="@string/third" /> <TextView android:id="@+id/fourthText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00FFFF" android:text="@string/fourth" /> </RelativeLayout>
<string name="first">First</string>
<string name="second">Second</string>
<string name="third">Third</string>
<string name="fourth">Fourth</string>
為了清晰展示,從一到四標籤的背景顏色為白黃紅綠,注意看上面沒有定義任何相對位置屬性,結果:
都重合到一起了,這說明在沒有定義相對位置屬性的情況下,所有標籤都是相對於螢幕左上角佈局的,現在更改一下main.xml的程式碼:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/firstText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:layout_below="@id/firstText"
android:text="@string/second" />
<TextView
android:id="@+id/thirdText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF00FF"
android:layout_below="@id/secondText"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FFFF"
android:layout_below="@id/thirdText"
android:text="@string/fourth" />
</RelativeLayout>
從二開始、每個標籤都加了一個屬性android:layout_below,意思是該元件位於引用元件的下方,而引用的元件就是這個屬性值裡面的內容“@id/要引用的id名”。然後再執行一下,看結果:
OK,符合預期,這就是相對佈局,下面列出所有的位置屬性以及他們代表的意思,參考一下:
android:layout_above 位於引用元件的上方
android:layout_below 位於引用元件的下方
android:layout_toLeftOf 位於引用元件的左方
android:layout_toRightOf 位於引用元件的右方
android:layout_alignParentTop 是否對齊父元件的頂部
android:layout_alignParentBottom 是否對齊父元件的底部
android:layout_alignParentLeft 是否對齊父元件的左端
android:layout_alignParentRight 是否齊其父元件的右端
android:layout_centerInParent 是否相對於父元件居中
android:layout_centerHorizontal 是否橫向居中
android:layout_centerVertical 是否垂直居中
另外可能會用到:ViewGroup.LayoutParams.WRAP_CONTENT,在main.java中可以動態新增控制元件,這個是新增的控制元件長寬自適應內容。
佈局二:
線性佈局LinearLayout,按照垂直或者水平的順序依次排列子元素(如果不指定,預設為水平),每一個子元素都位於前一個元素之後。這樣形成單行N列,或者單列N行的佈局;如果想要N行N列,可以巢狀使用LinearLayout。先看看效果:
layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/firstText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:text="@string/second" />
<TextView
android:id="@+id/thirdText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF00FF"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FFFF"
android:text="@string/fourth" />
</LinearLayout>
這裡沒有指定任何屬性,顯示如下,可以看到4個標籤水平依次排列:
現在略微修改一下程式碼,在LinearLayout節點內新增屬性android:orientation="vertical",顯示如下:
再來演示下N行N列的佈局方法,使用巢狀結構,還是main.xml程式碼:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/firstText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:text="@string/second" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/thirdText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF00FF"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FFFF"
android:text="@string/fourth" />
</LinearLayout>
</LinearLayout>
所得效果如下:(注意每個TextView裡面的android:layout_width和android:layout_height的屬性值,有興趣的可以試試不同的值顯示的不同的效果)
這個佈局中還有個android:layout_weight屬性限定在水平佈局時,不同的控制元件佔的寬度比率,具體規則為:如果水平佈局有兩個控制元件,其android:layout_weight屬性值分別為n和m,則屬性值為n的控制元件所佔的長度比例為總長的n/(n+m),屬性值為m的控制元件所佔的長度比例為m/(n+m);屬性值越大,佔的份額越多。
這裡再演示一下,main.xml中四個控制元件分別加上android:layout_weight=“對應的數字”:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/firstText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="#FFFF00"
android:text="@string/second" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/thirdText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#FF00FF"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="4"
android:background="#00FFFF"
android:text="@string/fourth" />
</LinearLayout>
</LinearLayout>
顯示效果:
另外還能通過LinearLayout的android:gravity屬性或者控制元件的android:layout_gravity屬性,結合LinearLayout的android:orientation屬性來設定水平或者垂直居中,這個可以自己多除錯一下。
佈局三:
表格佈局TableLayout,更方便的展示N行N列的佈局格式。TableLayout由許多TableRow組成,每個TableRow都代表一行。
TableRow繼承自LinearLayout,android:orientation="horizontal",android:layout_width=“match_parent”,android:layout_height =“wrap_content”。裡面定義的控制元件都是橫向排列,並且寬高一致的,相當於表格中的單元格,但是不能合併單元格。
看程式碼,layout/main.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/firstText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFF00"
android:text="@string/second" />
</TableRow>
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/thirdText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FF00FF"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#00FFFF"
android:text="@string/fourth" />
</TableRow>
</TableLayout>
效果圖:(有興趣的可以去掉android:layout_weight屬性看看效果)
關於表格佈局需要了解的還有:
android:stretchColumns某一列自動填充空白區域
android:shrinkColumns壓縮某個列(用於內容過長,橫向顯示不完全,多餘的往下自動擴充套件)
TableLayout的列序號從0開始
android:gravity設定對齊規則可以多個條件中間用|分開,比如android:gravity=“top|right”,注意|前後不能有空格
佈局四:
單幀佈局FrameLayout,理解起來最簡單,所有的控制元件都不能指定位置,從左上角對齊依次疊加,後面的控制元件直接覆蓋在前面的控制元件之上。為了清晰的顯示出效果,這裡使用兩種不同的控制元件大小展示。
layout/main.xml程式碼:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/firstText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:text="@string/second" />
<TextView
android:id="@+id/thirdText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF00FF"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FFFF"
android:text="@string/fourth" />
</FrameLayout>
顯示效果:(因為second比fourth長那麼一點點,所以露出來一點)
換個程式碼再演示一下main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/firstText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#FFFF00"
android:text="@string/second" />
<TextView
android:id="@+id/thirdText"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#FF00FF"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#00FFFF"
android:text="@string/fourth" />
</FrameLayout>
效果:
佈局五:
絕對佈局AbsoluteLayout,使用android:layout_x和android:layout_y屬性來限定控制元件的位置,左上角座標為(0,0),各控制元件位置可以重疊,實際開發中因為限定的位置太過死板而很少用到,實際上我使用的版本已經提示這個佈局過期,不推薦使用,這裡簡單介紹一下。
layout/main.xml程式碼:
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/firstText"
android:layout_x="50dp"
android:layout_y="50dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#FFFFFF"
android:text="@string/first" />
<TextView
android:id="@+id/secondText"
android:layout_x="80dp"
android:layout_y="80dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#FFFF00"
android:text="@string/second" />
<TextView
android:id="@+id/thirdText"
android:layout_x="120dp"
android:layout_y="100dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#FF00FF"
android:text="@string/third" />
<TextView
android:id="@+id/fourthText"
android:layout_x="180dp"
android:layout_y="10dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#00FFFF"
android:text="@string/fourth" />
</AbsoluteLayout>
效果:
佈局到此為止,不同的佈局之間還可以巢狀,大家有興趣的話可以自己多嘗試嘗試。