1. 程式人生 > >Android系統五大布局詳解Layout

Android系統五大布局詳解Layout

  我們知道Android系統應用程式一般是由多個Activity組成,而這些Activity以檢視的形式展現在我們面前,檢視都是由一個一個的元件構成的。元件就是我們常見的Button、TextEdit等等。那麼我們平時看到的Android手機中那些漂亮的介面是怎麼顯示出來的呢?這就要用到Android的佈局管理器了,網上有人比喻的很好:佈局好比是建築裡的框架,元件按照佈局的要求依次排列,就組成了用於看見的漂亮介面了。

      在分析佈局之前,我們首先看看控制元件:Android中任何視覺化的控制元件都是從android.veiw.View繼承而來的,系統提供了兩種方法來設定檢視:第一種也是我們最常用的的使用XML檔案來配置View的相關屬性,然後在程式啟動時系統根據配置檔案來建立相應的View檢視。第二種是我們在程式碼中直接使用相應的類來建立檢視。

     如何使用XML檔案定義檢視:

      每個Android專案的原始碼目錄下都有個res/layout目錄,這個目錄就是用來存放佈局檔案的。佈局檔案一般以對應activity的名字命名,以 .xml 為字尾。在xml中為建立元件時,需要為元件指定id,如:android:id="@+id/名字"系統會自動在gen目錄下建立相應的R資源類變數。 

    如何在程式碼中使用檢視: 

     在程式碼中建立每個Activity時,一般是在onCreate()方法中,呼叫setContentView()來載入指定的xml佈局檔案,然後就可以通過findViewById()來獲得在佈局檔案中建立的相應id的控制元件了,如Button等。

 如:

[html] view plaincopyprint?
  1. private Button btnSndMag;  
  2. public void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.main);  // 載入main.xml佈局檔案  
  5.     btnSndMag = (Button)this.findViewById(R.id.btnSndMag); // 通過id找到對於的Button元件  
  6.     ....  
  7. }  
  

  下面我們來介紹Android系統中為我們提供的五大布局:LinearLayout(線性佈局)、FrameLayout(單幀佈局)、AbsoluteLayout(絕對佈局)、TablelLayout(表格佈局)、RelativeLayout(相對佈局)。其中最常用的的是LinearLayout、TablelLayout和RelativeLayout。這些佈局都可以巢狀使用。

(1)LinearLayout 線性佈局

  線性佈局是按照水平或垂直的順序將子元素(可以是控制元件或佈局)依次按照順序排列,每一個元素都位於前面一個元素之後。線性佈局分為兩種:水平方向和垂直方向的佈局。分別通過屬性android:orientation="vertical" 和 android:orientation="horizontal"來設定。

 android:layout_weight 表示子元素佔據的空間大小的比例,有人說這個值大小和佔據空間成正比,有人說反比。我在實際應用中設定和網上資料顯示的剛好相反,這個問題後面會專門寫一篇文章來分析。現在我們只需要按照正比例來設定就可以。 

例如下面我們實現一個如圖所示的簡易計算器介面:


程式碼:

[html] view plaincopyprint?
  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:orientation="vertical"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:background="#FFFFFF"
  7.     tools:context=".MainActivity">
  8.     // 這裡第一行顯示標籤為一個水平佈局  
  9.     <LinearLayout
  10.         android:layout_width="match_parent"
  11.         android:layout_height="wrap_content"
  12.         android:orientation="horizontal">
  13.         <EditText
  14.             android:id="@+id/msg"
  15.             android:inputType="number"
  16.             android:layout_width="match_parent"
  17.             android:layout_height="wrap_content"
  18.             android:text="">
  19.         </EditText>
  20.     </LinearLayout>
  21.     // 第二行為 mc m+ m- mr 四個Button構成一個水平佈局  
  22.     <LinearLayout
  23.         android:layout_width="match_parent"
  24.         android:layout_height="wrap_content"
  25.         android:orientation="horizontal">
  26.         <Button
  27.             android:layout_width="match_parent"
  28.             android:layout_height="wrap_content"
  29.             android:text="mc"android:layout_weight="1">
  30.         </Button>
  31.         <Button
  32.             android:layout_width="match_parent"
  33.             android:layout_height="wrap_content"
  34.             android:text="m+"android:layout_weight="1">
  35.         </Button>
  36.         <Button
  37.             android:layout_width="match_parent"
  38.             android:layout_height="wrap_content"
  39.             android:text="m-"android:layout_weight="1">
  40.         </Button>
  41.         <Button
  42.             android:layout_width="match_parent"
  43.             android:layout_height="wrap_content"
  44.             android:text="mr"android:layout_weight="1">
  45.         </Button>
  46.     </LinearLayout>
  47.     // 同上 C +/-  / * 四個Button構成一個水平佈局  
  48.       <LinearLayout
  49.           android:layout_width="match_parent"
  50.           android:layout_height="wrap_content"
  51.           android:orientation="horizontal">
  52.           <Button
  53.               android:layout_width="match_parent"
  54.               android:layout_height="wrap_content"
  55.               android:layout_weight="1"
  56.               android:text="C">
  57.           </Button>
  58.           <Button
  59.               android:layout_width="match_parent"
  60.               android:layout_height="wrap_content"
  61.               android:layout_weight="1"
  62.               android:text="+/-">
  63.           </Button>
  64.           <Button
  65.               android:layout_width="match_parent"
  66.               android:layout_height="wrap_content"
  67.               android:layout_weight="1"
  68.               android:text="/">
  69.           </Button>
  70.           <Button
  71.               android:layout_width="match_parent"
  72.               android:layout_height="wrap_content"
  73.               android:layout_weight="1"
  74.               android:text="*">
  75.           </Button>
  76.       </LinearLayout>
  77.       <LinearLayout
  78.         android:layout_width="match_parent"
  79.         android:layout_height="wrap_content"
  80.         android:orientation="horizontal">
  81.         <Button
  82.             android:layout_width="match_parent"
  83.             android:layout_height="wrap_content"
  84.             android:text="7"android:layout_weight="1">
  85.         </Button>
  86.         <Button
  87.             android:layout_width="match_parent"
  88.             android:layout_height="wrap_content"
  89.             android:text="8"android:layout_weight="1">
  90.         </Button>
  91.         <Button
  92.             android:layout_width="match_parent"
  93.             android:layout_height="wrap_content"
  94.             android:text="9"android:layout_weight="1">
  95.         </Button>
  96.         <Button
  97.             android:layout_width="match_parent"
  98.             android:layout_height="wrap_content"
  99.             android:text="-"android:layout_weight="1">
  100.         </Button>
  101.     </LinearLayout>
  102.     <LinearLayout
  103.         android:layout_width="match_parent"
  104.         android:layout_height="wrap_content"
  105.         android:orientation="horizontal">
  106.         <Button
  107.             android:layout_width="match_parent"
  108.             android:layout_height="wrap_content"
  109.             android:layout_weight="1"
  110.             android:text="4">
  111.         </Button>
  112.         <Button
  113.             android:layout_width="match_parent"
  114.             android:layout_height="wrap_content"
  115.             android:layout_weight="1"
  116.             android:text="5">
  117.         </Button>
  118.         <Button
  119.             android:layout_width="match_parent"
  120.             android:layout_height="wrap_content"
  121.             android:layout_weight="1"
  122.             android:text="6">
  123.         </Button>
  124.         <Button
  125.             android:layout_width="match_parent"
  126.             android:layout_height="wrap_content"
  127.             android:layout_weight="1"
  128.             android:text="+">
  129.         </Button>
  130.     </LinearLayout>
  131.     // 最外層是一個水平佈局,由左邊上面一行1 2 3三個Button,下面一行的0 . 兩個Button 和 右邊的=構成  
  132.      <LinearLayoutandroid:orientation="horizontal"
  133.         android:layout_width="match_parent"
  134.         android:layout_height="wrap_content">
  135.         // 這裡 1 2 3 和 下面的 0 . 構成一個垂直佈局  
  136.         <LinearLayoutandroid:orientation="vertical"
  137.             android:layout_weight="3"
  138.             android:layout_width="wrap_content"
  139.             android:layout_height="wrap_content">
  140.             // 這裡的 1 2 3 構成一個水平佈局  
  141.             <LinearLayoutandroid:orientation="horizontal"
  142.                 android:layout_width="match_parent"
  143.                 android:layout_height="wrap_content">
  144.                 <Button
  145.                     android:layout_width="wrap_content"
  146.                     android:layout_height="wrap_content"
  147.                     android:layout_weight="1"
  148.                     android:text="1"></Button>
  149.                 <Button
  150.                     android:layout_width="wrap_content"
  151.                     android:layout_height="wrap_content"
  152.                     android:layout_weight="1"
  153.                     android:text="2"></Button>
  154.                 <Button
  155.                     android:layout_width="wrap_content"
  156.                     android:layout_height="wrap_content"
  157.                     android:layout_weight="1"
  158.                     android:text="3"></Button>
  159.             </LinearLayout>
  160.             // 這裡的 0 和 . 構成一個水平佈局,注意這裡的android_weight引數設定  
  161.             <LinearLayoutandroid:orientation="horizontal"
  162.                 android:layout_width="match_parent"
  163.                 android:layout_height="wrap_content">
  164.                 <Button
  165.                     android:layout_width="0px"
  166.                     android:layout_height="wrap_content"
  167.                     android:layout_weight="2"
  168.                     android:text="0"></Button>
  169.                 <Button
  170.                     android:layout_width="0px"
  171.                     android:layout_height="wrap_content"
  172.                     android:layout_weight="1"
  173.                     android:text="."></Button>
  174.             </LinearLayout>
  175.         </LinearLayout>
  176.         // 這裡一個單獨Button構成的垂直佈局  
  177.         <LinearLayoutandroid:orientation="vertical"
  178.             android:layout_weight="1"
  179.             android:layout_width="wrap_content"
  180.             android:layout_height="match_parent">
  181.             <Button
  182.                 android:layout_width="match_parent"
  183.                 android:layout_height="match_parent"
  184.                 android:text="="></Button>
  185.         </LinearLayout>
  186.      </LinearLayout>
  187. </LinearLayout>

(2)TableLayout 表格佈局

         表格佈局,適用於多行多列的佈局格式,每個TableLayout是由多個TableRow組成,一個TableRow就表示TableLayout中的每一行,這一行可以由多個子元素組成。實際上TableLayout和TableRow都是LineLayout線性佈局的子類。但是TableRow的引數android:orientation屬性值固定為horizontal,且android:layout_width=MATCH_PARENT,android:layout_height=WRAP_CONTENT。所以TableRow實際是一個橫向的線性佈局,且所以子元素寬度和高度一致。

       注意:在TableLayout中,單元格可以為空,但是不能跨列,意思是隻能不能有相鄰的單元格為空。

        在TableLayout佈局中,一列的寬度由該列中最寬的那個單元格指定,而該表格的寬度由父容器指定。可以為每一列設定以下屬性:

     Shrinkable  表示該列的寬度可以進行收縮,以使表格能夠適應父容器的大小

     Stretchable 表示該列的寬度可以進行拉伸,以使能夠填滿表格中的空閒空間

     Collapsed  表示該列會被隱藏

TableLayout中的特有屬性:

android:collapseColumns

        android:shrinkColumns

        android:stretchColumns = "0,1,2,3"// 表示產生4個可拉伸的列

Demo:我們想設計一個如下所以的一個三行三列的表格,但是第二行我們只想顯示2個表格:


[java] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:orientation="vertical"
  4.     android:shrinkColumns="0,1,2"// 設定三列都可以收縮  
  5.     android:stretchColumns="0,1,2"// 設定三列都可以拉伸 如果不設定這個,那個顯示的表格將不能填慢整個螢幕
  6.     android:layout_width="fill_parent"
  7.     android:layout_height="fill_parent" >      
  8.     <TableRow android:layout_width="fill_parent"
  9.         android:layout_height="wrap_content">  
  10.         <Button android:gravity="center"
  11.             android:padding="10dp"
  12.             android:text="Button1">  
  13.         </Button>  
  14.         <Button android:gravity="center"
  15.             android:padding="10dp"
  16.             android:text="Button2">  
  17.         </Button>  
  18.         <Button android:gravity="center"
  19.             android:padding="10dp"
  20.             android:text="Button3">  
  21.         </Button>  
  22.     </TableRow>  
  23.     <TableRow android:layout_width="fill_parent"
  24.         android:layout_height="wrap_content">  
  25.         <Button android:gravity="center"
  26.             android:padding="10dp"
  27.             android:text="Button4">  
  28.         </Button>  
  29.         <Button android:gravity="center"
  30.             android:padding="10dp"
  31.             android:text="Button5">  
  32.         </Button>  
  33.     </TableRow>  
  34.     <TableRow android:layout_width="fill_parent"
  35.         android:layout_height="wrap_content">  
  36.         <Button android:gravity="center"
  37.             android:padding="10dp"
  38.             android:text="Button6">  
  39.         </Button>       
  40.         <Button android:gravity="center"
  41.             android:padding="10dp"
  42.             android:text="Button7">  
  43.         </Button>  
  44.         <Button android:gravity="center"
  45.             android:padding="10dp"
  46.             android:text="Button8">  
  47.         </Button>  
  48.     </TableRow>  
  49. </TableLayout>  


(3)RelativeLayout 相對佈局

   RelativeLayout繼承於android.widget.ViewGroup,其按照子元素之間的位置關係完成佈局的,作為Android系統五大布局中最靈活也是最常用的一種佈局方式,非常適合於一些比較複雜的介面設計。

   注意:在引用其他子元素之前,引用的ID必須已經存在,否則將出現異常。

常用的位置屬性:

[java] view plaincopyprint?
  1. android:layout_toLeftOf         該元件位於引用元件的左方  
  2. android:layout_toRightOf        該元件位於引用元件的右方  
  3. android:layout_above            該元件位於引用元件的上方  
  4. android:layout_below                該元件位於引用元件的下方  
  5. android:layout_alignParentLeft      該元件是否對齊父元件的左端  
  6. android:layout_alignParentRight     該元件是否齊其父元件的右端  
  7. android:layout_alignParentTop       該元件是否對齊父元件的頂部  
  8. android:layout_alignParentBottom    該元件是否對齊父元件的底部  
  9. android:layout_centerInParent       該元件是否相對於父元件居中  
  10. android:layout_centerHorizontal     該元件是否橫向居中  
  11. android:layout_centerVertical       該元件是否垂直居中  

Demo:利用相對佈局設計一個如下圖所示的介面:


原始碼:

[html] view plaincopyprint?
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent">
  5.     <Buttonandroid:id="@+id/btn1"
  6.         android:layout_width="wrap_content"
  7.         android:layout_height="wrap_content"
  8.         android:layout_centerInParent="true"
  9.         android:layout_centerHorizontal="true"
  10.         android:text="Button1"
  11.         ></Button>
  12.     <Buttonandroid:id="@+id/btn2"
  13.         android:layout_width="wrap_content"
  14.         android:layout_height="wrap_content"
  15.         android:layout_toLeftOf="@id/btn1"
  16.         android:layout_above="@id/btn1"
  17.         android:text="Button2"
  18.         ></Button>
  19.     <Buttonandroid:id="@+id/btn3"
  20.         android:layout_width="wrap_content"
  21.         android:layout_height="wrap_content"
  22.         android:layout_toRightOf="@id/btn1"
  23.         android:layout_above="@id/btn1"
  24.         android:text="Button3"
  25.         ></Button>
  26.     <Buttonandroid:id="@+id/btn4"
  27.         android:layout_width="wrap_content"
  28.         android:layout_height="wrap_content"
  29.         android:layout_toRightOf="@id/btn2"
  30.         android:layout_toLeftOf="@id/btn3"
  31.         android:layout_above="@id/btn2"
  32.         android:text="Button4"
  33.         ></Button>
  34. </RelativeLayout>

(4)FrameLayout 框架佈局

 將所有的子元素放在整個介面的左上角,後面的子元素直接覆蓋前面的子元素,所以用的比較少。

(5) AbsoluteLayou 絕對佈局

   絕對佈局中將所有的子元素通過設定android:layout_x 和 android:layout_y屬性,將子元素的座標位置固定下來,即座標(android:layout_x, android:layout_y) ,layout_x用來表示橫座標,layout_y用來表示縱座標。螢幕左上角為座標(0,0),橫向往右為正方,縱向往下為正方。實際應用中,這種佈局用的比較少,因為Android終端一般機型比較多,各自的螢幕大小。解析度等可能都不一樣,如果用絕對佈局,可能導致在有的終端上顯示不全等。

除上面講過之外常用的幾個佈局的屬性:
(1)layout_margin 
用於設定控制元件邊緣相對於父控制元件的邊距
android:layout_marginLeft 
android:layout_marginRight
android:layout_marginTop
android:layout_marginBottom


(2) layout_padding 
用於設定控制元件內容相對於控制元件邊緣的邊距
android:layout_paddingLeft
android:layout_paddingRight
android:layout_paddingTop
android:layout_paddingBottom


(3) layout_width/height
用於設定控制元件的高度和寬度
wrap_content 內容包裹,表示這個控制元件的裡面文字大小填充
fill_parent跟隨父視窗
match_parent


(4) gravity 
用於設定View元件裡面內容的對齊方式
topbottomleft  right center等


(5) android:layout_gravity  
用於設定Container元件的對齊方式
android:layout_alignTop 本元素的上邊緣和某元素的的上邊緣對齊
android:layout_alignLeft 本元素的左邊緣和某元素的的左邊緣對齊
android:layout_alignBottom 本元素的下邊緣和某元素的的下邊緣對齊
android:layout_alignRight 本元素的右邊緣和某元素的的右邊緣對齊