1. 程式人生 > >頁面的五種佈局以及巢狀『Android系列八』

頁面的五種佈局以及巢狀『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的程式碼

<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>
        定義了4個文字標籤,各自的文字值(下面幾種佈局使用同樣的strings.xml檔案)
    <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>

        效果:


        佈局到此為止,不同的佈局之間還可以巢狀,大家有興趣的話可以自己多嘗試嘗試。