概述
布局(Layout)的概念是針對Activity的,Activity就是布滿整個Android設備的窗口或者懸浮於其他窗口上的交互界面。在一個應用程序中通常由多個Activity構成,每個需要顯示的Activity都需要在AndroidManifest.xml文件之中聲明。
通常情況下,開發人員可以使用兩種方式來創建UI組件,一種方式是使用XML方式來配置UI組件的相關屬性,然后裝載這些UI組件,這也是最常用的方式。但是有些特殊情況下,需要動態生成UI組件,則需要使用第二種方式,完全使用Java代碼來創建UI組件。
XML布局文件是Android系統中定義的Layout的常用方式,所有布局文件必須包含在res/layout目錄中,且必須符合Java的命名規范。當在res/layout目錄下新增了布局文件之后,R.java文件會自動收錄該布局資源,Java代碼可通過setContentView方法在Activity中顯示該Layout。
setContentView(R.layout.<資源名稱>);
Android應用的絕大部分UI組件都放在android.widget包及其子包、android.view包及其子包中,Android應用的所有UI組件都繼承了View類。View類還有一個重要的子類:ViewGroup,ViewGroup類是所有布局管理器的父類。
ViewGroup容器控制其子組件的分布依賴於ViewGroup.LayoutParams、ViewGroup.MarginLayoutParams兩個內部類。
ViewGroup.LayoutParams提供兩個XML屬性設定組件的大小。
- android:layout_height:指定該子組件的基本高度;
- android:layout_width:指定該子組件的基本寬度。
- fill_parent:指定組件的高度、寬度與父容器組件的一樣。
- match_parent:與fill_parent一樣,Android2.2開始推薦使用。
- warp_content:內容包裹。
- android:layout_marginBottom(下邊距);
- android:layout_marginLeft(左邊距);
- android:layout_marginRight(右邊距):
- layout_marginTop(上邊距)
對於View的尺寸,android提供了三種單位供選擇使用:
- px:像素。
- dp:dpi,表示屏幕實際的像素。
- sp:會根據系統設定的字體大小進行縮放,與dp類似,通常用於設置字體。
尺寸單位選擇的技巧:如果設置長度、高度等屬性時可以使用dp,但是如果設置字體,推薦使用sp。在屏幕適配方面,不推薦使用px,因為使用dp或者sp,UI會根據設備的density和scaledDensity進行等比例縮放,以達到不同屏幕適配的功效,讓其在不同的屏幕上看起來差不多的效果。
為了適應各種界面風格,Android提供了五種布局規范,利用這五種布局,基本上可以在設備上隨心所欲的擺放任何UI組件,這五種布局分別是:
- FrameLayout(幀布局)。
- LinearLayout(線性布局)
- RelativeLayout(相對布局)。
- TableLayout(表格布局)。
- AbsoluteLayout(絕對布局)。
線性布局(LinearLayout)
LinearLayout是最常用的布局方式,在XML文件中使用<LinearLayout>標記。它會將容器里的UI組件一個一個挨着排列起來。但是LinearLayout不會換行,當UI組件超出屏幕之后,則不會被顯示出來。LinearLayout有兩個重要的XML屬性:android:gravity(對齊方式);android:orientation(排列方式)。
android:orientation(排列方式),設定了LinearLayout中包含的UI組件的排列方式,有兩個選項vertical(豎向)、horizontal(橫向,默認值)
android:gravity(對齊方式),設定LinearLayout中包含UI組件的對齊方式,其選項很多,常用上(top)、下(bottom)、左(left)、右(right)。
LinearLayout布局示例:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context=".MainActivity" android:orientation="horizontal" android:gravity="bottom"> 6 <Button 7 android:layout_weight="1" 8 android:text="button" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content"/> 11 <Button 12 android:text="button" 13 android:layout_gravity="top" 14 android:layout_weight="1" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content"/> 17 <Button 18 android:text="button" 19 android:layout_weight="1" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content"/> 22 </LinearLayout>
顯示效果:
幀布局(FrameLayout)
幀布局是最簡單的布局方式,所有添加到這個布局中的視圖都是以層疊的方式顯示,並且后聲明的遮擋先聲明的控件。
幀布局容器為每個加入其中的組件創建一個空白的區域(稱為一幀),所有每個子組件占據一幀,這些幀都會根據gravity屬性執行自動對齊。
下面通過一個例子說明幀布局,以一個經典的漸變色條為例,在FrameLayout中以此添加多個TextView,賦予不同尺寸和顏色,會疊加顯示。
FrameLayout示例代碼:
1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context=".MainActivity" > 10 11 <TextView 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:width="210px" 15 android:height="50px" 16 android:background="#ff0000" 17 /> 18 <TextView 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:width="180px" 22 android:height="50px" 23 android:background="#dd0000" 24 /> 25 <TextView 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:width="150px" 29 android:height="50px" 30 android:background="#bb0000" 31 /> 32 <TextView 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:width="120px" 36 android:height="50px" 37 android:background="#990000" 38 /> 39 <TextView 40 android:layout_width="wrap_content" 41 android:layout_height="wrap_content" 42 android:width="90px" 43 android:height="50px" 44 android:background="#770000" 45 /> 46 <TextView 47 android:layout_width="wrap_content" 48 android:layout_height="wrap_content" 49 android:width="60px" 50 android:height="50px" 51 android:background="#550000" 52 /> 53 <TextView 54 android:layout_width="wrap_content" 55 android:layout_height="wrap_content" 56 android:width="30px" 57 android:height="50px" 58 android:background="#330000" 59 /> 60 </FrameLayout>
以上示例顯示效果圖:
相對布局(RelativeLayout)
RelativeLayout,其內子組件的位置總是相對兄弟UI組件、父親容器來決定的。比如UI組件A相對於UI組件B的位置進行定位,那么UI組件B需要在UI組件A之前定義。
相對布局用到的主要屬性:
- android:layout_below:在某元素的下方。
- android:layout_above:在某元素的上方。
- android:layout_toLeftOf:在某元素的左邊。
- android:layout_toRightOf:在某元素的右邊。
- android:layout_alignXxx:控制與某元素的邊界對其方式。
下面通過一個例子來說明RelativeLayout,在該布局XML中,確定一個經典的梅花布局效果,上下左右的UI組件通過中間的UI組件位置確定自己的位置。
示例代碼:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:gravity="top" 6 android:paddingBottom="@dimen/activity_vertical_margin" 7 android:paddingLeft="@dimen/activity_horizontal_margin" 8 android:paddingRight="@dimen/activity_horizontal_margin" 9 android:paddingTop="@dimen/activity_vertical_margin" 10 tools:context=".MainActivity" > 11 12 <TextView 13 android:id="@+id/view1" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:text="中" 17 android:layout_centerInParent="true" 18 /> 19 <TextView 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content" 22 android:text="上" 23 android:layout_above="@id/view1" 24 android:layout_alignLeft="@id/view1" 25 /> 26 <TextView 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:text="下" 30 android:layout_below="@id/view1" 31 android:layout_alignLeft="@id/view1" 32 /> 33 <TextView 34 android:layout_width="wrap_content" 35 android:layout_height="wrap_content" 36 android:text="左" 37 android:layout_toLeftOf="@id/view1" 38 android:layout_alignTop="@id/view1" 39 /> 40 <TextView 41 android:layout_width="wrap_content" 42 android:layout_height="wrap_content" 43 android:text="右" 44 android:layout_toRightOf="@id/view1" 45 android:layout_alignTop="@id/view1" 46 /> 47 </RelativeLayout>
效果展示
表格布局(TableLayout)
表格布局,采用行、列的形式來管理UI組件,TableLayout通過TableRow、其他UI組件來控制表格的行數和列數。
每次向TableLayout中添加一個TableRow,該TableRow就是一個表格行,TableRow也是容器,因此它也可以不斷添加其他組件,沒添加一個子組件,該表格就增加一列。如果直接向TableLayout中添加組件,那么這個組件將直接占用一行。
- android:collapseColumns:設置需要被隱藏的列序號。
- android:shrinkColumns:設置需要被收縮的列序號。
- android:stretchColumns:設置需要被拉伸的列序號。
注意:TableLayout中所謂的序列號是從0開始計算的。
下面用一個例子來說明TableLayout布局,代碼如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <TableLayout 8 android:layout_width="fill_parent" 9 android:layout_height="wrap_content" 10 android:stretchColumns="0,1,2,3" > 11 12 <TableRow 13 android:layout_width="fill_parent" 14 android:layout_height="wrap_content" > 15 16 <Button 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:text="button" /> 20 21 <Button 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content" 24 android:text="button" /> 25 26 <Button 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:text="button" /> 30 31 <Button 32 android:layout_width="wrap_content" 33 android:layout_height="wrap_content" 34 android:text="button" /> 35 </TableRow> 36 37 <EditText 38 android:layout_width="fill_parent" 39 android:layout_height="fill_parent" 40 android:background="#00ffff" /> 41 </TableLayout> 42 43 </LinearLayout>
展示效果:
絕對布局(AbsoluteLayout)
對於AbsoluteLayout,android不提供任何布局控制,而是由開發人員自己通過X坐標、Y坐標來控制組件的位置。
在AbsoluteLayout中,每個子組件都需要通過兩個XML屬性來確定坐標:layout_x:指定該子組件的X坐標;layout_y:指定該子組件的Y坐標。
因為此布局比較繁瑣,而且在不同的屏幕上顯示效果差距比較大,所以一般不推薦使用,下面通過一個簡單的示例來展示AbsoluteLayout的用法
示例代碼:
1 <?xml version="1.0" encoding="utf-8"?> 2 <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <EditText 8 android:id="@+id/editText1" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:layout_x="84dp" 12 android:layout_y="20dp" 13 android:ems="10" /> 14 15 <EditText 16 android:id="@+id/EditText01" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:layout_x="84dp" 20 android:layout_y="66dp" 21 android:ems="10" /> 22 23 <Button 24 android:id="@+id/button1" 25 android:layout_width="wrap_content" 26 android:layout_height="wrap_content" 27 android:layout_x="214dp" 28 android:layout_y="113dp" 29 android:text="重置" /> 30 31 <Button 32 android:id="@+id/button2" 33 android:layout_width="wrap_content" 34 android:layout_height="wrap_content" 35 android:layout_x="130dp" 36 android:layout_y="113dp" 37 android:text="登錄" /> 38 39 <TextView 40 android:id="@+id/textView1" 41 android:layout_width="wrap_content" 42 android:layout_height="wrap_content" 43 android:layout_x="33dp" 44 android:layout_y="36dp" 45 android:text="用戶名" /> 46 47 <TextView 48 android:id="@+id/textView2" 49 android:layout_width="wrap_content" 50 android:layout_height="wrap_content" 51 android:layout_x="48dp" 52 android:layout_y="80dp" 53 android:text="密碼" /> 54 55 </AbsoluteLayout>
展示效果: