我們知道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等。
如:
~~~
private Button btnSndMag;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // 加載main.xml布局文件
btnSndMag = (Button)this.findViewById(R.id.btnSndMag); // 通過id找到對于的Button組件
....
}
~~~
?
下面我們來介紹Android系統中為我們提供的五大布局:LinearLayout(線性布局)、FrameLayout(單幀布局)、AbsoluteLayout(絕對布局)、TablelLayout(表格布局)、RelativeLayout(相對布局)。其中最常用的的是LinearLayout、TablelLayout和RelativeLayout。這些布局都可以嵌套使用。
**(1)LinearLayout 線性布局**
線性布局是按照水平或垂直的順序將子元素(可以是控件或布局)依次按照順序排列,每一個元素都位于前面一個元素之后。線性布局分為兩種:水平方向和垂直方向的布局。分別通過屬性android:orientation="vertical" 和 android:orientation="horizontal"來設置。
android:layout_weight 表示子元素占據的空間大小的比例,有人說這個值大小和占據空間成正比,有人說反比。我在實際應用中設置和網上資料顯示的剛好相反,這個問題后面會專門寫一篇文章來分析。現在我們只需要按照正比例來設置就可以。?
例如下面我們實現一個如圖所示的簡易計算器界面:

代碼:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
tools:context=".MainActivity" >
// 這里第一行顯示標簽為一個水平布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/msg"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="">
</EditText>
</LinearLayout>
// 第二行為 mc m+ m- mr 四個Button構成一個水平布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mc" android:layout_weight="1">
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="m+" android:layout_weight="1">
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="m-" android:layout_weight="1">
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="mr" android:layout_weight="1">
</Button>
</LinearLayout>
// 同上 C +/- / * 四個Button構成一個水平布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="C" >
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+/-" >
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="/" >
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="*" >
</Button>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="7" android:layout_weight="1">
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="8" android:layout_weight="1">
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="9" android:layout_weight="1">
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="-" android:layout_weight="1">
</Button>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="4" >
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="5" >
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="6" >
</Button>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+" >
</Button>
</LinearLayout>
// 最外層是一個水平布局,由左邊上面一行1 2 3三個Button,下面一行的0 . 兩個Button 和 右邊的=構成
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
// 這里 1 2 3 和 下面的 0 . 構成一個垂直布局
<LinearLayout android:orientation="vertical"
android:layout_weight="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
// 這里的 1 2 3 構成一個水平布局
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1"></Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2"></Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="3"></Button>
</LinearLayout>
// 這里的 0 和 . 構成一個水平布局,注意這里的android_weight參數設置
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="0"></Button>
<Button
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="."></Button>
</LinearLayout>
</LinearLayout>
// 這里一個單獨Button構成的垂直布局
<LinearLayout android:orientation="vertical"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="="></Button>
</LinearLayout>
</LinearLayout>
</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個表格:

~~~
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:shrinkColumns="0,1,2" // 設置三列都可以收縮
android:stretchColumns="0,1,2" // 設置三列都可以拉伸 如果不設置這個,那個顯示的表格將不能填慢整個屏幕
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TableRow android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:gravity="center"
android:padding="10dp"
android:text="Button1">
</Button>
<Button android:gravity="center"
android:padding="10dp"
android:text="Button2">
</Button>
<Button android:gravity="center"
android:padding="10dp"
android:text="Button3">
</Button>
</TableRow>
<TableRow android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:gravity="center"
android:padding="10dp"
android:text="Button4">
</Button>
<Button android:gravity="center"
android:padding="10dp"
android:text="Button5">
</Button>
</TableRow>
<TableRow android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:gravity="center"
android:padding="10dp"
android:text="Button6">
</Button>
<Button android:gravity="center"
android:padding="10dp"
android:text="Button7">
</Button>
<Button android:gravity="center"
android:padding="10dp"
android:text="Button8">
</Button>
</TableRow>
</TableLayout>
~~~
**(3)RelativeLayout 相對布局**
?RelativeLayout繼承于android.widget.ViewGroup,其按照子元素之間的位置關系完成布局的,作為Android系統五大布局中最靈活也是最常用的一種布局方式,非常適合于一些比較復雜的界面設計。
?注意:在引用其他子元素之前,引用的ID必須已經存在,否則將出現異常。
常用的位置屬性:
?
~~~
android:layout_toLeftOf 該組件位于引用組件的左方
android:layout_toRightOf 該組件位于引用組件的右方
android:layout_above 該組件位于引用組件的上方
android:layout_below 該組件位于引用組件的下方
android:layout_alignParentLeft 該組件是否對齊父組件的左端
android:layout_alignParentRight 該組件是否齊其父組件的右端
android:layout_alignParentTop 該組件是否對齊父組件的頂部
android:layout_alignParentBottom 該組件是否對齊父組件的底部
android:layout_centerInParent 該組件是否相對于父組件居中
android:layout_centerHorizontal 該組件是否橫向居中
android:layout_centerVertical 該組件是否垂直居中
~~~
Demo:利用相對布局設計一個如下圖所示的界面:

源碼:
~~~
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:text="Button1"
></Button>
<Button android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/btn1"
android:layout_above="@id/btn1"
android:text="Button2"
></Button>
<Button android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/btn1"
android:layout_above="@id/btn1"
android:text="Button3"
></Button>
<Button android:id="@+id/btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/btn2"
android:layout_toLeftOf="@id/btn3"
android:layout_above="@id/btn2"
android:text="Button4"
></Button>
</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 本元素的右邊緣和某元素的的右邊緣對齊
- 前言
- Android開發之serviceManager分析
- Android啟動之init.c文件main函數分析
- Android開發之ProcessState和IPCThreadState類分析
- Android開發之MediaPlayerService服務詳解(一)
- Android系統五大布局詳解Layout
- Android四大組件之Content Provider
- Android四大組件之Service
- Android四大組件之BroadcastReceiver
- Android系統中的消息處理Looper、Handler、Message
- Android EditText/TextView使用SpannableString顯示復合文本
- Android關鍵資源詳解
- Android常用適配器分析(如何制作簡易Launcher)
- Android常用列表控件