8.4 布局(Layout)

布局(Layout)是各个控件在屏幕上的位置关系,视图组的几个扩展类与布局相关。在 Android 中布局通常有以下几种不同的情况:


  • FrameLayout(框架布局):系统默认的在屏幕上就有空白区显示它;
  • LinearLayout(线性布局):让所有的子视图都成为单一的方向,即垂直的或者水平的;
  • AbsoluteLayout(绝对布局):让子视图使用 x/y 坐标确定在屏幕上的位置;
  • RelativeLayout(相对布局):让子视图的位置和其他的视图相关;
  • TableLayout(表单布局):位置是它的子视图的行或列。

FrameLayout、LinearLayout、RelativeLayout、AbsoluteLayout、TableLayout 都是扩展了 ViewGroup 的类,因此

这些视图可以用于包含其他的控件,并可以控制其他的控件的位置关系。布局的内容一般通过在布局文件中控制即可,在控制布局时 ​​android:layout_width​​ 和​​android:layout_height​​ 等表示尺寸属性,除了使用实际的尺寸值外,还有两个常用的选项:


  • “fill_parent”:表示能填满父视图的最大尺寸;
  • “wrap_content”:表示仅包裹子内容的最小尺寸。
    这两个值既可以在视图组中使用,也可以在普通视图中使用,如果在视图中使用"wrap_content",表示包裹其中的内容,例如按钮需要包裹上面的文字。

8.4.1.基本的布局内容

基本的布局内容用于控制每个元素的位置。示例程序位于 Views=>Layout=>Baseline 中:

布局文件:baseline_X.xml

其中的一些显示效果如图所示:

速读原著-Android应用开发入门教程(布局(Layout))_3d

左图的程序使用了默认的布局参数,因此是上对齐和左对齐的效果,中图的程序使用了 ​​android:layout_gravity​​为底部对齐,右图中使用了两个布局嵌套的方式:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/baseline_3_explanation" />
<LinearLayout
99
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_weight="1.0"
android:layout_height="0dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="3dip"
android:layout_gravity="center_vertical"
android:text="@string/baseline_3_label" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="3dip"
android:layout_gravity="center_vertical"
android:text="@string/baseline_3_button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="20sp"
android:text="@string/baseline_3_bigger" />
</LinearLayout>
</LinearLayout>

以上几个程序实际上使用的是线性布局( LinearLayout )。以上不同元素位置的控制通过定义​​android:layout_gravity​​ 属性来完成,​​android:layout_gravity​​ 可以在各个 View 中使用:top、bottom、left、right、

​center_vertical​​、​​fill_vertical​​、​​center_horizontal​​、​​fill_horizontal​​、​​center​​、fill、​​clip_vertical​​、​​clip_horizontal​​,这些选项用于处理竖直和水平方向的对齐方式。

8.4.2.线性布局(LinearLayout)

线性布局是 Android 中最常使用的布局,示例程序位于 ​​Views=>Layout=>LinearLayout​​ 中。线性布局程序的运行结果如图所示:

速读原著-Android应用开发入门教程(布局(Layout))_xml_02

这几个示例程序的布局文件分别为 ​​linear_layout_1.xml​​、​​linear_layout_2.xml​​ 和 ​​linear_ layout_4.xml​​。​​linear_ layout_4.xml​​ 的内容如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:background="@drawable/red"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:background="@drawable/green"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<!-- ……省略部分内容 -->
</LinearLayout>

左图和中图的差别在于左图的竖直方向使用了"​​wrap_content​​​",中图使用了"fill_parent";右图使用了​​android:orientation="horizontal"​​​定义屏幕中的方向为水平,并设置竖直方向为"​​fill_parent​​",因此其中的内容以竖直方向显示。

8.4.3.相对布局(RelativeLayout)

相对布局的特点是可以让控件之间互相确定关系,这样可以保证在屏幕的局部范围内几个控件之间的关系不受外部影响,

相对布局的示例程序位于 Views=>Layou=>RelativeLayout 中,其中的两个程序的运行结果如图所示:这两个示例程序的布局文件分别为 relative_layout_1.xml 和 relative_layout_2.xml。

速读原著-Android应用开发入门教程(布局(Layout))_android_03

左图通过设置 ​​android:layout_alignParentTop​​​ 和​​android:layout_alignParentBottom​​​ 两个属性为"true",让控件对齐到父 UI 的上端和下端。相关的属性还有 ​​android:layout_ alignParentRight​​​ 和​​android:layout_alignParentLeft​​。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/view1"
android:background="@drawable/red"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="@string/relative_layout_1_top"/>
<TextView
android:id="@+id/view2"
android:background="@drawable/green"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="@string/relative_layout_1_bottom"/>
<TextView
android:id="@+id/view3"
android:background="@drawable/yellow"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_above="@id/view2"
android:layout_below="@id/view1"
android:text="@string/relative_layout_1_center"/>
</RelativeLayout>

右图中的两个按钮使用了相对对齐的方式,它们之间的关系如下所示:

<Button android:id="@+id/ok" 
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/entry" android:layout_alignParentRight="true"
android:layout_marginLeft="10dip" android:text="@string/relative_layout_2_ok" />
<Button
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toLeftOf="@id/ok" android:layout_alignTop="@id/ok"
android:text="@string/relative_layout_2_cancel" />

“Cancel”按钮的位置是相对“Ok”按钮来确定的,toLeftOf 属性表示在“Ok”按钮的左侧,layout_alignTop属性表示和“Ok”按钮上对齐。

8.4.4.表单布局(Table Layout)

一个表单布局(TableLayout)包含了若干个 TableRow 对象,每一个 TableRow 对象定义了其中一行。TableLayout 中也包含了不显示的行和列的边沿。

参考示例程序:​​TableLayout1(Views=>Layout=>TabLayout=>01.basic)​

源代码:​​com/example/android/apis/view/TableLayout1.java​

布局文件:​​table_layout_1.xml​

表单布局程序的运行结果如图所示:

速读原著-Android应用开发入门教程(布局(Layout))_xml_04

这个示例程序的布局文件 table_layout_1.xml 的内容如下所示:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" android:layout_height="fill_parent">
<TableRow>
<TextView android:text="@string/table_layout_1_star"
android:padding="3dip" />
<TextView android:text="@string/table_layout_1_open"
android:padding="3dip" />
<TextView android:text="@string/table_layout_1_open_shortcut"
android:padding="3dip" />
</TableRow>
<TableRow>
<TextView android:text="@string/table_layout_1_triple_star"
android:padding="3dip" />
<TextView android:text="@string/table_layout_1_save"
android:padding=" 3dip" />
<TextView android:text="@string/table_layout_1_save_shortcut"
android:padding="3dip" />
</TableRow>
<!-- ……省略部分内容 -->
</TableLayout>

TableLayout 中包含了若干个 TableRow,每个 TableRow 中又包含了若干个 TextView,这样在 UI 上实际上就形成了一个隐性的表格,表格中的每一个单元格的内容是一个 View。这种表单布局,其实是用了类似 HTML中的表格的方式,这样可以准确地完成复杂的对齐问题。