Android 五大布局講解與應用

2016-02-28    分類:Android開發、程式設計開發、首頁精華1人評論發表於2016-02-28

本文由碼農網 – 楊小勇原創,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃

Android總體有五大布局:

  • 線性佈局(LiearLayout): 螢幕垂直或水平方向佈局。
  • 幀佈局(FrameLayout):控制元件從螢幕左上角開始佈局。
  • 相對佈局(RelativeLayout): 以其他控制元件為參照佈局。
  • 絕對佈局(AbsoluteLayout):以螢幕座標佈局。
  • 表格佈局(TableLayout):按照行列方式佈局。

一、LinearLayout

線性佈局在開發中使用最多,具有垂直方向與水平方向的佈局方式,通過設定屬性“android:orientation”控制方向,屬性值垂直(vertical)和水平(horizontal),預設水平方向。

在使用orientation時需要注意一個問題,假如我們使用預設佈局方向,即水平方向,若LinearLayout中存在不止一個控制元件且都未設定具體寬度,即這樣的佈局程式碼:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

則會出現下面的錯誤:

這個錯誤告訴我們在有多個子控制元件時需要設定佈局方向或至少設定一個子控制元件在該佈局方向的大小,我們可以顯示設定佈局方向或設定某一個子控制元件的寬度。

除orientation之外還有以下常用屬性:

android:gravity:內部控制元件對齊方式,常用屬性值有center、center_vertical、center_horizontal、top、bottom、left、right等。這個屬性在佈局元件RelativeLayout、TableLayout中也有使用,FrameLayout、AbsoluteLayout則沒有這個屬性。

center:居中顯示,這裡並不是表示顯示在LinearLayout的中心,當LinearLayout線性方向為垂直方向時,center表示水平居中,但是並不能垂直居中,此時等同於center_horizontal的作用;同樣當線性方向為水平方向時,center表示垂直居中,等同於center_vertical。

top、bottom、left、right顧名思義為內部控制元件居頂、低、左、右佈局。

這裡要與android:layout_gravity區分開,layout_gravity是用來設定自身相對於父元素的佈局。

android:layout_weight:權重,用來分配當前控制元件在剩餘空間的大小。正常情況下,值越大佔據高度或寬度越大。例外的情況,在LineayLayout佈局中使用這個屬性時需要注意: 當水平方向佈局且子控制元件的寬度為fill_parent或match_parent時,值越小佔據寬度越大,垂直方向也一樣。分析一下這種情況,類似這樣的程式碼:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#666666"
        android:text="第一個子控制元件"
        android:gravity="center"
        android:layout_weight="1"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#EE4000"
        android:text="第二個子控制元件"
        android:gravity="center"
        android:layout_weight="2"/>

</LinearLayout>

顯示效果:

這裡出現這種情況主要是因為match_parent或fill_parent引起的,系統先給第一個子控制元件分配parent_width(剩餘空間),再給第二個分配parent_width,即分配了兩個parent_width,此時剩餘為parent_width-2parent_width=-parent_width,這裡主要問題就在這裡,剩餘控制元件其實已經為一個負數了。接著,第一個控制元件佔寬度:parent_width(當前已有寬度)+權重1/3*(-parent_width)=2/3parent_width;第二個控制元件佔寬度:parent_width+權重2/3*(-parent_width)=1/3parent_width,所以當寬度都是match_parent時,剩餘空間則為負數,誰的權重大誰就會減去越多。

在平常開發中我們會經常用到這個屬性,通過設定layout_weight能解決很多不可思議的佈局問題。

二、FrameLayout

幀佈局或叫層佈局,從螢幕左上角按照層次堆疊方式佈局,後面的控制元件覆蓋前面的控制元件。該佈局在開發中經常用到,因為是按層次方式佈局,我們需要實現層面顯示的樣式時就可以採用這種佈局方式,比如我們要實現一個類似百度地圖的佈局:

通過這張圖我們可以看到地圖與操作按鈕是分層顯示的,運用FrameLayout我們也可以簡單實現這樣的樣式,程式碼如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/mapShowView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="40sp"
        android:background="@drawable/edit_selector"
        android:layout_marginLeft="20sp"
        android:layout_marginRight="20sp"
        android:layout_marginTop="30dp"
        android:paddingLeft="10sp"
        android:textSize="14sp"
        android:hint="搜地點、查公交、找路線"
        android:textColorHint="#aaaaaa"
        android:gravity="left|center_vertical"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_gravity="right"
        android:layout_marginTop="80dp"
        android:layout_marginRight="20dp">

        <Button
            android:id="@+id/traffic"
            android:layout_width="45sp"
            android:layout_height="45sp"
            android:text="路況"
            android:textColor="#ffffff"
            android:textSize="14sp"
            android:background="@drawable/corner_black_bgborder"/>

        <Button
            android:id="@+id/panorama"
            android:layout_width="45sp"
            android:layout_height="45sp"
            android:text="全景"
            android:textColor="#ffffff"
            android:textSize="14sp"
            android:layout_marginTop="10dp"
            android:background="@drawable/corner_black_bgborder"/>

        <Button
            android:id="@+id/company"
            android:layout_width="45sp"
            android:layout_height="45sp"
            android:text="同行"
            android:textColor="#ffffff"
            android:textSize="14sp"
            android:layout_marginTop="10dp"
            android:background="@drawable/corner_black_bgborder"/>

    </LinearLayout>

    <Button
        android:id="@+id/location"
        android:layout_width="45sp"
        android:layout_height="45sp"
        android:layout_gravity="bottom"
        android:text="定位"
        android:textColor="#ffffff"
        android:textSize="14sp"
        android:layout_marginLeft="20dp"
        android:layout_marginBottom="120dp"
        android:background="@drawable/corner_black_bgborder"/>
</FrameLayout>

顯示效果:

FrameLayout中第一個子控制元件為百度地圖,其次為輸入框、右邊操作按鈕與左下方定位按鈕。我們可以看到這裡很多子控制元件都使用了一個屬性,layout_gravity,正如前面講解gravity屬性提到的一樣,layout_gravity用來設定自身相對於父元素的佈局,這個屬性在FrameLayout佈局時會經常使用到,用來控制控制元件在佈局中的位置,layout_gravity常用屬性值有top、bottom、left、right、center、center_horizontal、center_vertical,這裡的center可以讓控制元件居於FrameLayout的中心佈局,屬性值可以複合使用,比如我們既要居底部佈局又要垂直居中就可以這樣設定:“android:layout_gravity=bottom|center_vertical”。

程式碼中的操作控制元件分三個佈局位置,頂部的搜尋框、右邊的操作按鈕、左下方的定位按鈕。以下為這三部分的講解:

  1. 搜尋輸入框,根據FrameLayout的定義,子控制元件從佈局的左上角開始按照層次堆疊方式佈局,這裡輸入框,我們需要顯示在螢幕的上方,所以只需要設定它的上、左、右方向的margin就可以滿足我們的設計。這裡讓輸入框水平居中顯示的方式是通過設定寬度為match_parent再設定左右方向相同的margin就可以水平居中,當然也可以通過設定一定的寬度後再設定layout_gravity的屬性值為center_horizontal。
  2. 右邊操作按鈕欄,三個按鈕為LinearLayout佈局,垂直方向線性佈局,LinearLayout中我們設定“android :layout_gravity=right”來讓實現靠右佈局,其次設定margin讓控制元件按照合理的佈局顯示。
  3. 定位按鈕,這個按鈕顯示在螢幕的左下方,我們只需要設定“android :layout_gravity=bottom”,再設定方向的margin讓按鈕顯示在合理的位置。

三、RelativeLayout

相對佈局可以讓子控制元件相對於兄弟控制元件或父控制元件進行佈局,可以設定子控制元件相對於兄弟控制元件或父控制元件進行上下左右對齊。RelativeLayout能替換一些巢狀檢視,當我們用LinearLayout來實現一個簡單的佈局但又使用了過多的巢狀時,就可以考慮使用RelativeLayout重新佈局。

RelativeLayout中子控制元件常用屬性:

1、相對於父控制元件,例如:android:layout_alignParentTop=“true”

android:layout_alignParentTop      控制元件的頂部與父控制元件的頂部對齊;

android:layout_alignParentBottom  控制元件的底部與父控制元件的底部對齊;

android:layout_alignParentLeft      控制元件的左部與父控制元件的左部對齊;

android:layout_alignParentRight     控制元件的右部與父控制元件的右部對齊;

2、相對給定Id控制元件,例如:android:layout_above=“@id/**”

android:layout_above 控制元件的底部置於給定ID的控制元件之上;

android:layout_below     控制元件的底部置於給定ID的控制元件之下;

android:layout_toLeftOf    控制元件的右邊緣與給定ID的控制元件左邊緣對齊;

android:layout_toRightOf  控制元件的左邊緣與給定ID的控制元件右邊緣對齊;

android:layout_alignBaseline  控制元件的baseline與給定ID的baseline對齊;

android:layout_alignTop        控制元件的頂部邊緣與給定ID的頂部邊緣對齊;

android:layout_alignBottom   控制元件的底部邊緣與給定ID的底部邊緣對齊;

android:layout_alignLeft       控制元件的左邊緣與給定ID的左邊緣對齊;

android:layout_alignRight      控制元件的右邊緣與給定ID的右邊緣對齊;

3、居中,例如:android:layout_centerInParent=“true”

android:layout_centerHorizontal 水平居中;

android:layout_centerVertical    垂直居中;

android:layout_centerInParent  父控制元件的中央;

應用例項:

<?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">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@drawable/topbar_bg_border">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="標題"
            android:textSize="19sp"
            android:textStyle="bold"
            android:textColor="#4e6288"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="15dp"
            android:text="取消"
            android:textSize="18sp"/>

    </RelativeLayout>

</LinearLayout>

顯示結果:

這是一個頂部佈局樣式,在很多app中我們會考慮使用樣式基本相同的頂部佈局來統一風格。這只是一個簡單的佈局,包含一個Title以及取消按鈕(這裡用的TextView代替),相對於其他幾個佈局控制元件,RelativeLayout在這裡使用起來更簡單也更合理。首先設定RelativeLayout的高度,再設定Title的android:layout_centerInParent=”true”顯示在中央,最後設定取消按鈕的兩個屬性垂直居中android:layout_centerVertical=”true”和右部對齊android:layout_alignParentRight=”true”。

四、AbsoluteLayout

絕對佈局也叫座標佈局,指定控制元件的絕對位置,簡單直接,直觀性強,但是手機螢幕尺寸差別較大,適應性差,Android 1.5已棄用,可以用RelativeLayout替代。

AbsoluteLayout實現佈局程式碼:

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

   <ImageView
       android:layout_width="100dip"
       android:layout_height="120dip"
       android:layout_x="150dip"
       android:layout_y="40dip"
       android:src="@drawable/android_logo"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="100dip"
        android:layout_y="150dip"
        android:text="上一張"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="200dip"
        android:layout_y="150dip"
        android:text="下一張"/>

    </AbsoluteLayout>

顯示效果:

這裡為了設計一個圖片瀏覽的效果,將各個控制元件的layout_x與layout_y依次設定了一遍,然而當前螢幕尺寸能正常顯示,其他螢幕就需要重新制定佈局。其實用RelativeLayout輕鬆就能實現這樣的效果,還不用考慮螢幕相容性。 所以,AbsoluteLayout已成為android佈局中的歷史。

五、TableLayout

表格佈局繼承自LinearLayout,通過TableRow設定行,列數由TableRow中的子控制元件決定,直接在TableLayout中新增子控制元件會佔據整個一行。

TableLayout常用屬性:

android:shrinkColumns:設定可收縮的列,內容過多就收縮顯示到第二行

android:stretchColumns:設定可伸展的列,將空白區域填充滿整個列

android:collapseColumns:設定要隱藏的列

列的索引從0開始,shrinkColumns和stretchColumns可以同時設定。

子控制元件常用屬性:

android:layout_column:第幾列

android:layout_span:佔據列數

TableLayout例項程式碼:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="首頁"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center">

        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:stretchColumns="0,1,2"
            android:gravity="center">

           <TableRow>
               <TextView
                   android:layout_width="100dp"
                   android:layout_height="100dp"
                   android:layout_margin="5dp"
                   android:background="#e2a617"
                   android:text="檔案管理"
                   android:gravity="center"/>

               <TextView
                   android:layout_width="100dp"
                   android:layout_height="100dp"
                   android:layout_margin="5dp"
                   android:background="#0d637f"
                   android:text="應用商店"
                   android:gravity="center"/>

               <TextView
                   android:layout_width="100dp"
                   android:layout_height="100dp"
                   android:layout_margin="5dp"
                   android:background="#aa2266"
                   android:text="檔案管理"
                   android:gravity="center"/>
           </TableRow>

            <TableRow>
                <TextView
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    android:layout_margin="5dp"
                    android:background="#45e15f"
                    android:text="應用管理"
                    android:gravity="center"/>
                <TextView
                    android:layout_width="200dp"
                    android:layout_height="100dp"
                    android:layout_margin="5dp"
                    android:background="#3924a4"
                    android:text="應用中心"
                    android:gravity="center"
                    android:layout_span="2"/>
            </TableRow>

        </TableLayout>

    </LinearLayout>

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:background="#f5f5f5"
        android:stretchColumns="0,1,2,3"
        android:gravity="center_vertical">

        <TableRow>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="首頁" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="訊息" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="發現" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="我" />
        </TableRow>

    </TableLayout>

</LinearLayout>

顯示效果:

螢幕中心是一個類似Material佈局,底部是一個頁面切換的導航欄。底部佈局通過設定android:stretchColumns=”0,1,2,3″來讓四個按鈕同樣大小顯示並填充到整個寬度,中心區域主要使用android:stretchColumns=”0,1,2″填充顯示以及android:layout_span=”2″控制大內容跨列顯示。

佈局在Android介面中相當於建築物的框架,在開發中我們需要運用多種佈局來實現介面顯示需求,只有瞭解了各種佈局的顯示樣式與它們之間的差距,我們才能駕輕就熟、合理的佈局介面。

本文連結:http://www.codeceo.com/article/android-5-layout-usage.html
本文作者:碼農網 – 楊小勇
原創作品,轉載必須在正文中標註並保留原文連結和作者等資訊。]

相關文章