為什么需要布局管理器
為了更好地管理Android應(yīng)用的用戶界面里的各種組件吠各,Android提供了布局管理器蛮浑。通過使用布局管理器缰犁,Android應(yīng)用的圖形用戶界面具有良好的平臺(tái)無關(guān)性鹃共。通常來說,推薦使用布局管理器來管理組件的分布垛叨、大小,而不是直接設(shè)置組件位置和大小柜某。
線性布局
LinearLayout嗽元,線性布局。LinearLayout將容器內(nèi)的組件一個(gè)挨著一個(gè)地排列起來喂击。LinearLayout可以控制各組件橫向排列(通過設(shè)置android:orientation屬性控制)剂癌,也可控制各組件縱向排列。
# LinearLayout常用XML屬性及相關(guān)方法
XML屬性 | 相關(guān)方法 | 說明 |
---|---|---|
android:baselineAligned | setBaselineAligned(boolean) | 該屬性設(shè)為false翰绊,將會(huì)阻止該布局管理器與它的子元素的基線對(duì)齊 |
android:divider | setDividerDrawable(Drawable) | 設(shè)置垂直布局時(shí)兩個(gè)按鈕之間的分割線 |
android:gravity | setGravity(int) | 設(shè)置布局管理器內(nèi)組件的對(duì)齊方式佩谷。屬性有:top旁壮、bottom、left谐檀、right抡谐、center_vertical、fill_vertical桐猬、center_horizontal麦撵、fill_horizontal、center溃肪、fill免胃、clip_vertical、clip_horizontal乍惊。也可以同時(shí)指定多種對(duì)齊方式的組合 |
android:measureWithLargestChild | setMeasureWithLargestChildEnabled(boolean) | 當(dāng)該屬性設(shè)為true時(shí)杜秸,所有帶權(quán)重的子元素都會(huì)具有最大子元素的最小尺寸 |
android:orientation | setOrientation(int) | 設(shè)置布局管理器內(nèi)組件的排列方式,可以設(shè)置為horizontal(水平排列)润绎、vertical(垂直排列撬碟、默認(rèn)值) |
LinearLayout
包含的所有子元素都受LinearLayout.LayoutParams
控制,因此LinearLayout
包含的子元素可以額外指定如下屬性:
XML屬性 | 說明 |
---|---|
android:layout_gravity | 指定該子元素在LinearLayout中的對(duì)齊方式 |
android:layout_weight | 指定該子元素在LinearLayout中所占的權(quán)重 |
示例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="top"
>
<Button
android:id="@+id/bn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bn1"
/>
<Button
android:id="@+id/bn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bn2"
/>
<Button
android:id="@+id/bn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bn3"
/>
<Button
android:id="@+id/bn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bn4"
/>
<Button
android:id="@+id/bn5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bn5"
/>
</LinearLayout>
表格布局
表格布局TableLayout繼承了LinearLayout,因此它的本質(zhì)依然是線性布局管理器。表格布局采用行饮笛、列的形式來管理UI組件屋休,TableLayout并不需要明確地聲明包含多少行、多少列霉撵,而是通過添加TableRow、其它組件來控制表格的行數(shù)和列數(shù)。
在TableLayout
中励翼,列的寬度由該列中最寬的那個(gè)單元格決定,整個(gè)TableLayout
的寬度則取決于父容器的寬度(默認(rèn)總是占滿父容器本身)辜荠。
在TableLayout
中汽抚,可以為單元格設(shè)置以下三種行為方式:
-
Shrinkable
:如果某個(gè)列被設(shè)為Shrinkable
,那么該列的所有單元格的寬度可以被收縮伯病,以保證該表格能適應(yīng)父容器的寬度造烁。 -
Strechable
:如果某個(gè)列被設(shè)為Strechable
,那么該列的所有單元格的寬度可以被拉伸午笛,以保證組件能完全填滿表格空余空間惭蟋。 -
Collapsed
:如果某個(gè)列被設(shè)為Collapsed
,那么該列的所有單元格會(huì)被隱藏药磺。
TableLayout
支持LinearLayout
所有的XML屬性告组,此外,還支持上面的3中屬性:
XML屬性 | 相關(guān)方法 | 說明 |
---|---|---|
android:collapseColumns | setColumnCollapsed(int,boolean) | 設(shè)置需要被隱藏的列的列序號(hào)与涡,多個(gè)列序號(hào)之間用逗號(hào)隔開 |
android:shrinkColumns | setShrinkAllColumns(boolean) | 設(shè)置允許被收縮的列的列序號(hào)惹谐,多個(gè)列序號(hào)之間用逗號(hào)隔開 |
android:strechColumns | setStrechAllColumns(boolean) | 設(shè)置允許被拉伸的列的列序號(hào)持偏,多個(gè)列序號(hào)之間用逗號(hào)隔開 |
示例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- 定義第一個(gè)表格布局,指定第2列允許收縮氨肌,第3列允許拉伸 -->
<TableLayout android:id="@+id/TableLayout01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="2"
>
<!-- 直接添加按鈕鸿秆,它自己會(huì)占一行 -->
<Button android:id="@+id/ok1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="獨(dú)自一行的按鈕"
/>
<!-- 添加一個(gè)表格行 -->
<TableRow>
<!-- 為該表格行添加3個(gè)按鈕 -->
<Button android:id="@+id/ok2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="普通按鈕"
/>
<Button android:id="@+id/ok3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="收縮的按鈕"
/>
<Button android:id="@+id/ok4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拉伸的按鈕"
/>
</TableRow>
</TableLayout>
<!-- 定義第二個(gè)表格布局 ,指定第二列隱藏-->
<TableLayout android:id="@+id/TableLayout01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:collapseColumns="1"
>
<!-- 直接添加按鈕怎囚,它自己會(huì)占一行 -->
<Button android:id="@+id/ok5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" 獨(dú)自一行的按鈕 "
/>
<!--定義一個(gè)表格行-->
<TableRow>
<!-- 為該表格行添加3個(gè)按鈕 -->
<Button android:id="@+id/ok6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="普通按鈕1"
/>
<Button android:id="@+id/ok7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="被隱藏的按鈕"
/>
<Button android:id="@+id/ok8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="普通按鈕 3"
/>
</TableRow>
</TableLayout>
<!-- 定義第三個(gè)表格布局 卿叽,指定第2、3兩列可以被拉伸-->
<TableLayout android:id="@+id/TableLayout01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1,2"
>
<!-- 直接添加按鈕恳守,它自己會(huì)占一行 -->
<Button android:id="@+id/ok9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="獨(dú)自一行的按鈕"
/>
<!--定義一個(gè)表格行-->
<TableRow>
<!-- 為該表格行添加3個(gè)按鈕 -->
<Button android:id="@+id/ok10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="普通按鈕"
/>
<Button android:id="@+id/ok11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拉伸的按鈕"
/>
<Button android:id="@+id/ok12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拉伸的按鈕"
/>
</TableRow>
<!--定義一個(gè)表格行-->
<TableRow>
<!-- 為該表格行添加2個(gè)按鈕 -->
<Button android:id="@+id/ok13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="普通按鈕"
/>
<Button android:id="@+id/ok14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拉伸的按鈕"
/>
</TableRow>
</TableLayout>
</LinearLayout>
幀布局
FramleLayout為每個(gè)加入其中的組件創(chuàng)建一個(gè)空白的區(qū)域(稱為一幀)考婴,每個(gè)子組件占據(jù)一幀,這些幀都會(huì)根據(jù)gravity屬性執(zhí)行自動(dòng)對(duì)齊催烘。
# FrameLayout的常用XML屬性及相關(guān)方法
XML屬性 | 相關(guān)方法 | 說明 |
---|---|---|
android:foreground | setForeground(Drawable) | 設(shè)置該幀布局容器的前景圖像 |
android:foregroundGravity | setForeground(int) | 定義繪制前景圖像的gravity屬性 |
FrameLayout
包含的子元素也受FrameLayout.LayoutParams
控制沥阱,因此它所包含的子元素也可指定android:layout_gravity
屬性,該屬性控制該子元素在FrameLayout
中的對(duì)齊方式伊群。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- 依次定義6個(gè)TextView,先定義的TextView位于底層
后定義的TextView位于上層 -->
<TextView android:id="@+id/view01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="320px"
android:height="320px"
android:background="#f00"
/>
<TextView android:id="@+id/view02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="280px"
android:height="280px"
android:background="#0f0"
/>
<TextView android:id="@+id/view03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="240px"
android:height="240px"
android:background="#00f"
/>
<TextView android:id="@+id/view04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="200px"
android:height="200px"
android:background="#ff0"
/>
<TextView android:id="@+id/view05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="160px"
android:height="160px"
android:background="#f0f"
/>
<TextView android:id="@+id/view06"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:width="120px"
android:height="120px"
android:background="#0ff"
/>
</FrameLayout>
相對(duì)布局
RelativeLayout
內(nèi)子組件的位置總是相對(duì)兄弟組件考杉、父容器來決定的,因此這種布局方式被稱為相對(duì)布局舰始。
如果A組件的位置是由B組件的位置來決定的崇棠,Android要求先定義B組件,再定義A組件丸卷。
# RelativeLayout的XML屬性及相關(guān)方法說明
XML屬性 | 相關(guān)方法 | 說明 |
---|---|---|
android:gravity | setGravity(int) | 設(shè)置該布局容器內(nèi)各子組件的對(duì)齊方式 |
android:ignoreGravity | setIgnoreGravity(int) | 設(shè)置哪個(gè)組件不受gravity屬性的影響 |
為了控制該布局容器中各子組件的布局分布枕稀,RelativeLayout
提供了一個(gè)內(nèi)部類:RelativeLayout.LayoutParams
,該類提供了大量的XML屬性來控制RelativeLayout布局容器中子組件的布局分布谜嫉。
RelativeLayout.LayoutParams里只能設(shè)為boolean值得屬性
XML屬性 | 說明 |
---|---|
android:layout_centerHorizontal | 控制該子組件是否位于布局容器的水平居中 |
android:layout_centerVertical | 控制該子組件是否位于布局容器的垂直居中 |
android:layout_centerInParent | 控制該子組件是否位于布局容器的中央位置 |
android:layout_alignParentBottom | 控制該子組件是否與布局容器底部對(duì)齊 |
android:layout_centerParentLeft | 控制該子組件是否位于布局容器左邊對(duì)齊 |
android:layout_centerParentRight | 控制該子組件是否位于布局容器右邊對(duì)齊 |
android:layout_centerParentTop | 控制該子組件是否位于布局容器頂端對(duì)齊 |
# RelativeLayout.LayoutParams里只能設(shè)為其它UI組件ID的屬性
XML屬性 | 說明 |
---|---|
android:layout_toRightOf | 控制該子組件位于給出ID組件的右側(cè) |
android:layout_toLeftOf | 控制該子組件位于給出ID組件的左側(cè) |
android:layout_above | 控制該子組件位于給出ID組件的上方 |
android:layout_below | 控制該子組件位于給出ID組件的下方 |
android:layout_alignTop | 控制該子組件位于給出ID組件的上邊界對(duì)齊 |
android:layout_alignBottom | 控制該子組件位于給出ID組件的下邊界對(duì)齊 |
android:layout_alignLeft | 控制該子組件位于給出ID組件的左邊界對(duì)齊 |
android:layout_alignRight | 控制該子組件位于給出ID組件的右邊界對(duì)齊 |
此外萎坷,RelativeLayout.LayoutParams
還繼承了android.view.ViewGroup.MarginLayoutParams
,因此RelativeLayout
布局容器中每個(gè)子組件也可指定android.view.ViewGroup.MarginLayoutParams
所支持的各XML屬性沐兰。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- 定義該組件位于父容器中間 -->
<TextView
android:id="@+id/view01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/leaf"
android:layout_centerInParent="true"
/>
<!-- 定義該組件位于view01組件的上方 -->
<TextView
android:id="@+id/view02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/leaf"
android:layout_above="@id/view01"
android:layout_alignLeft="@id/view01"
/>
<!-- 定義該組件位于view01組件的下方 -->
<TextView
android:id="@+id/view03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/leaf"
android:layout_below="@id/view01"
android:layout_alignLeft="@id/view01"
/>
<!-- 定義該組件位于view01組件的左邊 -->
<TextView
android:id="@+id/view04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/leaf"
android:layout_toLeftOf="@id/view01"
android:layout_alignTop="@id/view01"
/>
<!-- 定義該組件位于view01組件的右邊 -->
<TextView
android:id="@+id/view05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/leaf"
android:layout_toRightOf="@id/view01"
android:layout_alignTop="@id/view01"
/>
</RelativeLayout>
網(wǎng)格布局
GridLayout是Android4.0新增的布局管理器食铐,因此需要在Android4.0之后的版本中才能使用該布局管理器。如果希望在更早的Android平臺(tái)上使用該布局管理器僧鲁,則需要導(dǎo)入相應(yīng)的支持庫(kù)。
GridLayout
的作用類似于HTML
中的table
標(biāo)簽象泵,它把整個(gè)容器劃分成row x columns
個(gè)網(wǎng)格寞秃,每個(gè)網(wǎng)格可以放置一個(gè)組件。也可以設(shè)置一個(gè)組件橫跨多少列偶惠、一個(gè)組件縱跨多少行春寿。
# GridLayout的XML屬性及相關(guān)方法說明
XML屬性 | 相關(guān)方法 | 說明 |
---|---|---|
android:alignmentMode | setAlignmentMode(int) | 設(shè)置該布局管理器采用的對(duì)齊模式 |
android:columnCount | setColumnCount(int) | 設(shè)置該網(wǎng)格的列數(shù)量 |
android:rowCount | setRowOrderPreserved(boolean) | 設(shè)置該網(wǎng)格的行數(shù)量 |
android:columnOrderPreserved | setColumnOrderPreserved(boolean) | 設(shè)置該網(wǎng)格容器是否保留列序號(hào) |
android:rowOrderPreserved | setRowOrderPreserved(boolean) | 設(shè)置該網(wǎng)絡(luò)容器是否保留行序號(hào) |
android:useDefaultMargins | setUseDefaultMargins(boolean) | 設(shè)置該布局管理器是否使用默認(rèn)的頁邊距 |
為了控制GridLayout
布局容器中各子組件的布局分布,GridLayout
提供了一個(gè)內(nèi)部類:GridLayout.LayoutParams
忽孽,該類提供了大量的XML屬性來控制GridLayout
布局容器中子組件的布局分布绑改。
# GridLayout.LayoutParams的XML屬性及相關(guān)方法說明
XML屬性 | 相關(guān)方法 | 說明 |
---|---|---|
android:layout_gravity | setGravity | 設(shè)置該子組件采用何種方式占據(jù)該網(wǎng)格的空間 |
android:layout_column | 設(shè)置該子組件在GridLayout的第幾列 | |
android:layout_row | 設(shè)置該子組件在GridLayout的第幾行 | |
android:layout_columnSpan | 設(shè)置該子組件在GridLayout橫向上跨幾列 | |
android:layout_rowSpan | 設(shè)置該子組件在GridLayout縱向上跨幾行 |
示例:
<?xml version="1.0" encoding="utf-8" ?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="6"
android:columnCount="4"
android:id="@+id/root"
>
<!-- 定義一個(gè)橫跨4列的文本框谢床,
并設(shè)置該文本框的前景色、背景色等屬性 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:textSize="50sp"
android:layout_marginLeft="4px"
android:layout_marginRight="4px"
android:padding="5px"
android:layout_gravity="right"
android:background="#eee"
android:textColor="#000"
android:text="0"/>
<!-- 定義一個(gè)橫跨4列的按鈕 -->
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_columnSpan="4"
android:text="清除"/>
</GridLayout>
絕對(duì)布局
AbsoluteLayout厘线,就是Android不提供任何布局控制识腿,由開發(fā)者自己通過X坐標(biāo)、Y坐標(biāo)來控制組件的位置造壮。當(dāng)使用AbsoluteLayout作為布局容器時(shí)渡讼,布局容器不再管理子組件的位置、大小——這些都需要開發(fā)者自己控制耳璧。
注意:
大部分時(shí)候成箫,使用絕對(duì)布局都不是一個(gè)好思路。因?yàn)檫\(yùn)行Android應(yīng)用的手機(jī)往往千差萬別旨枯,因此屏幕大小蹬昌、分辨率都可能存在較大差異,使用絕對(duì)布局會(huì)很難兼顧不同屏幕大小攀隔、分辨率的問題皂贩。因此AbsoluteLayout布局管理器已經(jīng)過時(shí)。
使用絕對(duì)布局時(shí)竞慢,每個(gè)子組件都可指定如下兩個(gè)XML屬性:
-
layout_x
:指定該子組件的X坐標(biāo) -
layout_y
:指定該子組件的Y坐標(biāo)
示例:
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- 定義一個(gè)文本框先紫,使用絕對(duì)定位 -->
<TextView
android:layout_x="20dip"
android:layout_y="20dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用戶名:"
/>
<!-- 定義一個(gè)文本編輯框,使用絕對(duì)定位 -->
<EditText
android:layout_x="80dip"
android:layout_y="15dip"
android:layout_width="wrap_content"
android:width="200px"
android:layout_height="wrap_content"
/>
<!-- 定義一個(gè)文本框筹煮,使用絕對(duì)定位 -->
<TextView
android:layout_x="20dip"
android:layout_y="80dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密 碼:"
/>
<!-- 定義一個(gè)文本編輯框遮精,使用絕對(duì)定位 -->
<EditText
android:layout_x="80dip"
android:layout_y="75dip"
android:layout_width="wrap_content"
android:width="200px"
android:layout_height="wrap_content"
android:password="true"
/>
<!-- 定義一個(gè)按鈕,使用絕對(duì)定位 -->
<Button
android:layout_x="130dip"
android:layout_y="135dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登 錄"
/>
</AbsoluteLayout>
上面的界面布局中指定各組件的android:layout_x
败潦、android:layout_y
屬性時(shí)指定了形如20dip
這樣的屬性值本冲,這是一個(gè)距離值。Android中一般支持如下常用的距離單位:
-
px(像素)
:每個(gè)px
對(duì)應(yīng)屏幕上的一個(gè)點(diǎn) -
dip或dp(device independent pixels劫扒,設(shè)備獨(dú)立像素)
:一種基于屏幕密度的抽象單位檬洞。在每英寸160的顯示器上,1dip=1px沟饥。但隨著屏幕密度的改變添怔,dip與px的換算會(huì)發(fā)生改變。 -
sp(scaled pixels贤旷,比例像素)
:主要處理字體的大小广料,可以根據(jù)用戶的字體大小首選項(xiàng)進(jìn)行縮放
-in(英寸)
:標(biāo)準(zhǔn)長(zhǎng)度單位 -
mm(毫米)
:標(biāo)準(zhǔn)長(zhǎng)度單位 -
pt(磅)
:標(biāo)準(zhǔn)長(zhǎng)度單位,1/72英寸