為了更好的管理Android應用的用戶界面裡的個組件,Android提供了佈局管理器,通過佈局管理器,Android應用的圖形用戶界面具有良好的平台無關性。這裡什麼叫平台的無關性呢?就是說不同手機。我們知道不同手機它們的屏幕的分辨率、尺寸並不完全相同,而Android的佈局管理器可以根據運行平台來調整組件的大小,而我們所需要做的就是選擇合適的佈局管理器。
與Swing編程不同的是,Android的佈局管理器本身就是一個UI組件,所有的佈局管理器都是ViewGroup的子類:
我們從上圖也可以發現,所有佈局都可作為容器類使用,因此可以調用多個重載的addView() 向佈局管理器中添加組件,當然我們也可以用一個佈局管理器嵌套其他佈局管理器。
一、線性佈局
線性佈局是由LinearLayout 類來代表的,線性佈局有點像AWT 編程裡的FlowLayout ,它們都會將容器裡的組件一個挨著一個排列起來,LinearLayout 不僅可以控制各組件橫向排列,也可以控制縱向排列(android:orientation="vertical" 控制);
線性佈局與AWT 中FlowLayout 的組大區別在於:Android 的線性佈局不會換行,當組件一個挨著一個排到頭了,剩下的組件將不會被顯示出來。在Awt 中FlowLayout 則會另起一行排列多出來的組件。
LinearLayout 的常用XML 屬性及相關方法
XML 屬性 |
相關方法 |
說明 |
Android:gravity |
setGravity(int) |
設置佈局管理器內組件對齊方式,該屬性支持top、buttom 、left 、center_vertical 、等等,可以同時指定多種對齊方式,多個屬性值用豎線隔開,豎線前後不能有空格 |
android:orientation |
setOrientation(int) |
設置佈局管理器內組件的排列方式,vertical: 垂直,默認horizontal: 水平 |
通過Activity代碼的形式完成佈局,此時就不需要xml配置文件了
- package com.iflytek.activity;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.ViewGroup;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- public class LayoutProjectActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // setContentView(R.layout.main);
- // setContentView(R.layout.linearlayout);
- LinearLayout linearLayout = new LinearLayout(this);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT);
- linearLayout.setOrientation(LinearLayout.VERTICAL);
- LinearLayout.LayoutParams txtParams = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- TextView textView = new TextView(this);
- textView.setLayoutParams(txtParams);
- textView.setText("xdwang");
- textView.setTextSize(20);
- linearLayout.addView(textView);
- super.setContentView(linearLayout, layoutParams);
- }
- }
二、表格佈局
表格佈局由TableLayout 所代表,表格佈局採用行列的形式管理UI 組件,TableLayout 並不需要明確的聲明包含多少行、多少列,而是通過添加TableRow 、其他組件來控制表格的行數和列數。
每次向TableLayout 中添加一個TableRow ,該TableRow 就是一個表格行,TableRow 也是容器,因此它也可以不斷地添加其他組件,每添加一個子組件該表格就增加一列。
如果直接向TableLayout 中添加組件,那麼這個組件將直接佔用一行。
在表格佈局中,列的寬度由該列中最寬的那個單元格決定,整個表格佈局的寬度則取決與父容器的寬度(默認總是佔滿父容器本身)
在表格佈局管理器中,可以為單元格設置如下三種行為方式:
Shrinkable :如果某個列被設為Shrinkable ,那麼該列的所有單元格的寬度可以被收縮,以保證表格能適應父容器的寬度。
Stretchable :如果某個列被設為Stretchable ,那麼該列的所有單元格的寬度可以被拉伸,以保證組件能完全填滿表格空餘空間。
Collapsed :如果某個列被設為Collapsed ,那麼該列的所有單元格會被隱藏;
TableLayout 繼承了LinearLaout ,因此它完全可以支持LinearLayout 所支持的全部XML 屬性,除此之外,TableLayout 還支持如下表所示的XML 屬性。
Tab1eLayout 的常用XML 屬性及相關方法:
XML 屬性 |
相關方法 |
說明 |
android:collapseColumns |
setColumnCollapsed(int,boolean) |
設置需要被隱藏的列的列序號,多個列序號之間用逗號隔開 |
android:shrinkColumns |
setShrinkAllColumns(boolean) |
設置允許被收縮的列的列序號,多個列序號之間用逗號隔開 |
android:stretchColumns |
setStretchAllColumns(boolean) |
設置允許被拉伸的列的列序號,多個列序號之間用逗號隔開 |
tablelayout.xml(佈局排列):
- <?xml version="1.0" encoding="utf-8"?>
- <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TableRow >
- <EditText
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="請輸入內容" />
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="查詢" />
- </TableRow>
- <View
- android:layout_height="2px"
- android:background="#ccc"/>
- <!-- 分割線 -->
- <TableRow >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="20px"
- android:text="請選擇語言" />
- <RadioGroup
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:checkedButton="@+id/rb1"
- android:orientation="vertical">
- <RadioButton
- android:id="@+id/rb1"
- android:text="java"/>
- <RadioButton
- android:id="@+id/rb2"
- android:text="C#"/>
- </RadioGroup>
- </TableRow>
- </TableLayout>
Tablelayout2.xml(數據顯示):
- <?xml version="1.0" encoding="utf-8"?>
- <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical"
- android:shrinkColumns="2"
- android:collapseColumns="0,1"
- android:background="@drawable/james">
- <!--android:shrinkColumns="2",表示第3列為伸縮列 (因為下面的郵箱太長了,會將地址撐開,看不見的)-->
- <!--android:collapseColumns="0,1"設置不顯示列,如果有更多的列,則使用,分割 -->
- <TableRow >
- <TextView
- android:layout_column="0"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="ID" />
- <!-- android:layout_column,這個沒有提示,規定出了表格的列的編號 -->
- <!-- android:gravity="center_horizontal"表示居中顯示 -->
- <TextView
- android:layout_column="1"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="姓名" />
- <TextView
- android:layout_column="2"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="郵箱" />
- <TextView
- android:layout_column="3"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="地址" />
- </TableRow>
- <View
- android:layout_height="2px"
- android:background="#ccc"/>
- <!-- 分割線 -->
- <TableRow >
- <TextView
- android:layout_column="0"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="xdwang" />
- <TextView
- android:layout_column="1"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="王旭東" />
- <TextView
- android:layout_column="2"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="xdwangiflytek@gmail.com" />
- <TextView
- android:layout_column="3"
- android:gravity="center_horizontal"
- android:padding="8px"
- android:text="安徽合肥" />
- </TableRow>
- </TableLayout>
Activity動態生成
- package com.iflytek.activity;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.ViewGroup;
- import android.widget.TableLayout;
- import android.widget.TableRow;
- import android.widget.TextView;
- public class LayoutProjectActivity extends Activity {
- private String titleData[][] = new String[][] { { "ID", "姓名", "郵箱", "地址" },
- { "xdwang", "王旭東", "xdwangiflytek@gmail.com", "安徽合肥" },
- { "xdwang2", "王旭東2", "xdwangiflytek2@gmail.com", "安徽合肥" } };
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- TableLayout tableLayout = new TableLayout(this);
- TableLayout.LayoutParams tableParams= new TableLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
- tableLayout.setBackgroundResource(R.drawable.james);
- //設置表格行
- for (int i = 0; i < this.titleData.length; i++) {
- TableRow tableRow = new TableRow(this);
- for (int j = 0; j <this.titleData[i].length; j++) {
- TextView textView = new TextView(this);
- textView.setText(this.titleData[i][j]);
- tableRow.addView(textView, j);//加入一個編號
- }
- tableLayout.addView(tableRow);//向表格中增加若干表格行
- }
- super.setContentView(tableLayout, tableParams);
- }
- }
通過程序代碼實現的表格佈局本身比較麻煩的,一般更多的情況下是使用配置文件的形式完成。
三、幀佈局 (框架佈局)
幀佈局由FrameLayout 所代表,FrameLayout 直接繼承了ViewCroup 組件。
幀佈局容器為每個加入其中的組件創建一個空白的區域〔稱為一幀) ,所有每個子組件佔據一幀,這些幀都會根據gravity 屬性執行自動對齊。也就是說,幀佈局的效果有點類似於AWT 編程的CardLayout ,都是把組件一個一個地疊加在一起。與CardLayout 的區別在於,CardLayout 可以將下面的Card 移上來,但FrameLayout 則沒有提供相應的方法.
FrameLayout 的常用XML 屬性及相關方法
XML 屬性 |
相關方法 |
說明 |
android:foreground |
setForeground(Drawable) |
設置該幀佈局容器的前景圖像 |
android:foregroundGravity |
setForegroundGravity(int) |
定義繪製前景圖像的gravity 屬性 |
android:measureAllChildren |
setMeasureAllChildren(boolean) |
Determines whether to measure all children or just those in the VISIBLE or INVISIBLE state when measuring. |
Activity動態添加幀框架佈局
- package com.iflytek.activity;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.ViewGroup;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.FrameLayout;
- import android.widget.ImageView;
- public class LayoutProjectActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- FrameLayout frameLayout = new FrameLayout(this);
- FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT);
- FrameLayout.LayoutParams viewParams = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- ImageView imageView = new ImageView(this);
- imageView.setImageResource(R.drawable.james);
- EditText editText = new EditText(this);
- editText.setText("這裡是內容");
- Button button = new Button(this);
- button.setText("按鈕");
- frameLayout.addView(imageView, viewParams);
- frameLayout.addView(editText, viewParams);
- frameLayout.addView(button, viewParams);
- super.setContentView(frameLayout, frameParams);
- }
- }
四、相對佈局
相對佈局由 RelativeLayout 代表,相對佈局容器內子組件的位置總是相對兄弟組件、父容器來決定的,因此這種佈局方式被稱為相對佈局。
如果A 組件的位置是由B 組件的位置來決定的,Android 要求先定義B 組件,再定義A 組件。
RelativeLayout 的常用XML 屬性及相關方法
XML 屬性 |
相關方法 |
說明 |
android:gravity |
setGravity(int) |
設置該佈局棄器內部各子組件的對齊方式 |
android:ignoreGravity |
setIgnoreGravity(int) |
設置哪個組件不受gravity 組件的影響 |
為了控制該佈局容器中各子組件的佈局分佈,RelativeLayout 提供了一個內部類:
RelativeLayout.LayoutParams, 該類提供了大量的XML 屬性來控制RelativeLayout 佈局容器中子組件的佈局分佈。
relativelayout.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/rlId"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="horizontal" >
- <ImageView
- android:id="@+id/iv1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/james"/>
- <!-- 以組件id確定參考位置 -->
- <ImageView
- android:id="@+id/iv2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_launcher"
- android:layout_toRightOf="@id/iv1"/>
- <!-- 放在第一張圖片的右邊 -->
- <TextView
- android:id="@+id/tv1"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/iv2"
- android:layout_toRightOf="@id/iv1"
- android:text="@string/hello" />
- </RelativeLayout>
Activity動態生成:
- package com.iflytek.activity;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.ViewGroup;
- import android.widget.EditText;
- import android.widget.RelativeLayout;
- public class LayoutProjectActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- super.setContentView(R.layout.relativelayout);// 要讀取已經存在的佈局管理器
- RelativeLayout relativeLayout = (RelativeLayout) super
- .findViewById(R.id.rlId);
- RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT);
- relativeParams.addRule(RelativeLayout.LEFT_OF, R.id.tv1);
- relativeParams.addRule(RelativeLayout.BELOW, R.id.iv1);
- EditText editText = new EditText(this);
- relativeLayout.addView(editText, relativeParams);
- }
- }
五、絕對佈局
絕對佈局由AbsoluteLayout 代表。是Android2.3.3版本之前的佈局管理器,已廢棄了。絕對佈局就像Java AWT 編程中的空佈局,就是Android 不提供任何佈局控制,而是由開發人員自己通過X 坐標、Y 坐標來控制組件的位置。當使用AbsoluteLayout 作為佈局容器時,佈局容器不再管理子組件的位置、大小—這些都需要開發人員自己控制。
使用絕對佈局時,每個子組件都可指定如下兩個XML 屬性。
layout_x :指定該子組件的X 坐標。
layout_y :指定該子組件的Y 坐標
佈局管理器的嵌套
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <!-- 首先外面定義一個總的佈局管理器,一般來說用的最多的還是線性和表格兩種佈局 -->
- <Button
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="查詢" />
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <!-- 注意這裡的高度不能再全部鋪滿了,否則下面的佈局都沒空間了 -->
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/james"/>
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/ic_launcher"/>
- </LinearLayout>
- <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <TableRow>
- <EditText
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="這是什麼呢" />
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="這是什麼呢" />
- </TableRow>
- </TableLayout>
- </LinearLayout>