1.1. Android常用布局
Android的常用布局种类不多,然而却构成了Android界面的整体框架。本节,我们来介绍Android的四种常用布局,它们分别是线性布局LinearLayout,相对布局RelativeLayout,帧布局FrameLayout,表格布局TableLayout。
孔明:其实除了这四个布局之外还有一个绝对布局AbsoluteLayout,不过已经惨遭Google的抛弃。忘了它吧~ |
1.1.1.帧布局FrameLayout
帧布局FrameLayout是五大布局中最简单的一个布局。FrameLayout很神秘,是因为用到它的地方少。所有的帧布局子控件统统放在这个布局的左上角,并且后面的子控件直接覆盖在前面的子控件之上,将前面的子控件部分和全部遮挡。因此FrameLayout常用于需要有子控件覆盖的情况下,比如需要在一个ImageView上加一个按钮等。为了验证这一效果,我们在工程里面新增加一个类,命名为FrameLayoutActivity,其内容如下:
FrameLayoutActivity.java代码清单5-29:
/**
* FrameLayout展示类
* @author孔明
*/
publicclass FrameLayoutActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_layout);
}
}
从代码上看,唯一的一个操作就是在onCreate()方法里面设置了一下布局,这个Activity是用的布局文件是frame_layout.xml,内容如下:
frame_layout.xml代码清单5-29:
<?xml version=“1.0” encoding=“utf-8”?>
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextViewandroid:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="TextView1"/>
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="30sp"
android:text="TextView2"/>
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextView3"/>
</FrameLayout>
运行程序,截图如图5-46所示:
图5-46 帧布局示意图
我们可以看到第二个和第三个TextView在界面的上面,而第一个TextView的文字确显示在中间,这是因为第一个TextView的高度配置为fill_parent,而第二个和第三个高度为wrap_content。第三个TextView在第二个的上面,但是第二个的字体比第三个大而已。
孔明:帧布局是很少使用的一种布局,以至于很多开发者不知道还有这么一种布局,可以学来显摆显摆~ |
1.1.2.线性布局LinearLayout
线性布局LinearLayout是Android中特别常用的一个布局,线性布局将会按照线性的方式排列子控件。子控件可以按照横向或者竖向进行排列。当按照竖向进行排列时,每一行只能显示一个子控件。不管子控件的宽度为多少,当按照横向进行排列时,每一列只能显示一个控件。同样,不管子控件的高度为多少,当按照纵向进行排列时,每一行只能显示一个控件。因此如果需要多行多列的布局通常需要进行LinearLayout的嵌套,在一行或一列上放置多个LinearLayout。
LinearLayout在前面介绍控件的章节里面都有使用到,现在我们来展示一个多行多列的线性布局。在5.2.1的工程里面新增加一个类,命名为LinearLayoutActivity,Activity中内容与上一节5.3.1帧布局中的相同,只是这次使用的布局文件不同。本工程中使用的布局文件为linear_layout.xml,内容如下:
linear_layout.xml代码清单5-30:
<?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">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/solid_red"
android:text="第一行"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/solid_red"
android:layout_weight="1"
android:text="第二行1"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/solid_blue"
android:layout_weight="1"
android:text="第二行2"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/solid_red"
android:layout_weight="1"
android:text="第三行1"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/solid_blue"
android:layout_weight="2"
android:text="第三行2"/>
</LinearLayout>
</LinearLayout>
运行程序,得到如5-47界面:
图5-47 线性布局示意图
上面的例子中包含三行,第一行是一个TextView,第二行和第三行分别是一个LinearLayout,同时它们又分别包含两个TextView,其中的android:layout_weight设置不同。
android:layout_weight是LinearLayout中的一个很重要的属性,它是LinearLayout下面子控件的属性,用来描述子控件的重要程度,从而决定显示的大小。具体来说是在LinearLayout中把所有子View排布之后的剩余空间按照它们的layout_weight分配给各个拥有这个属性的View。layout_weight的默认值是0,意思是这个控件只占用本身的空间,不占用其他空间。如上例的图所示,它们的android:layout_weight值可以是同为1,这样会生成有两个等长的文本框。如果android:layout_weight值分别为设为1和2,那么第一个文本框将占据剩余空间的三分之二,第二个文本框将占据剩余空间中的三分之一。android:layout_weight遵循数值越小,重要度越高的原则。
LinearLayout中还有另外一个比较重要的属性就是android:orientation,此属性有两个可选的值,分别是horizontal和vertical,设置为horizontal将使得子控件按照横向排列,设置为vertical将使得子控件按照纵竖向排列。
1.1.3.相对布局RelativeLayout
相对布局RelativeLayout是按照各子控件之间的相对位置关系进行布局。在此布局中的子控件中与位置相关的属性将生效,例如android:layout_below,android:layout_above等。子控件就通过这些属性和各自的ID配合指定位置关系。注意在指定位置关系时,使用的ID必须先定义后,否则将出现异常。
RelativeLayout是Android五大布局结构中最灵活的一种布局结构,比较适合一些复杂界面的布局,下表是RelativeLayout中一些比较重要的xml属性。
属性名 | 属性值 |
layout_alignParentBottom | 当前控件低端与父控件的低端对齐(重合) |
layout_alignParentLeft | 当前控件左端与父控件的左端对齐(重合) |
layout_alignParentRight | 当前控件右端与父控件的右端对齐(重合) |
layout_alignParentTop | 当前控件上端与父控件的上端对齐(重合) |
layout_centerHorizontal | 当前控件位于父控件的横向中间位置(水平方向上的中间) |
layout_centerInParent | 当前控件位于父控件的纵横向中间位置(垂直方向上的中间) |
layout_centerVertical | 当前控件位于父控件的纵向中间位置(平面上的正中间) |
layout_above | 使当前控件位于给出id控件的上方 |
layout_below | 使当前控件位于给出id控件的下方 |
layout_toLeftOf | 使当前控件位于给出id控件的左侧 |
layout_toRightOf | 使当前控件位于给出id控件的右侧 |
layout_alignBottom | 使当前控件与给出id控件的底部部重合(注意可用和给出id控件来对齐) |
layout_alignLeft | 使当前控件与给出id控件的左边重合 |
layout_alignRight | 使当前控件与给出id控件的右边重合 |
layout_alignTop | 使当前控件与给出id控件的顶部重合 |
layout_alignBaseline | 使当前控件的BaseLine(文字书写的基准线)与给出id控件的BaseLine重合。这个主要用于Label或者其他包含文本的widgets。 |
下面,我们示例一下RelativeLayout该如何使用,在5.2.1的工程里面新建一个类,命名为RelativeLayoutActivity,新建一个布局文件relative_layout.xml,内容如下:
relative_layout.xml代码清单5-31:
<?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="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Button1"/>
<Button
android:id="@+id/btn2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button2"/>
<Button
android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn1"
android:layout_alignParentRight="true"
android:text="Button3"/>
<Button
android:id="@+id/btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn1"
android:layout_toLeftOf="@id/btn3"
android:text="Button4"/>
<Button
android:id="@+id/btn5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/btn2"
android:layout_alignParentLeft="true"
android:text="Button5"/>
<Button
android:id="@+id/btn6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/btn2"
android:layout_toRightOf="@id/btn5"
android:text="Button6"/>
</RelativeLayout>
运行程序之后截图如5-48所示:
图5-48 相对布局示意图
孔明:注意喽,线性布局和相对布局在编写需要屏幕适配的应用时特别好用,因此,在实际项目开发中,你们会发现这两个布局形式最常用到。 |
1.1.4.表格布局TableLayout
TableLayout顾名思义,此布局为表格布局,适用于N行N列的布局格式。一个TableLayout由许多TableRow组成,一个TableRow就代表TableLayout中的一行。
TableRow是LinearLayout的子类,它的android:orientation属性值恒为horizontal,并且它的android:layout_width和android:layout_height属性值恒为match_parent和wrap_content。所以它的子控件都是横向排列,并且宽高一致的。这样的设计使得每个TableRow里的子控件都相当于表格中的单元格一样。在TableRow中,单元格可以为空,但是不能跨列。
下面我们通过一个示例来演示一下TableLayout的布局结构,在工程里新增加一个类,命名为TableLayoutActivity,使用布局文件table_layout.xml内容如下:
table_layout.xml代码清单5-32:
<?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">
<!-- 第1个TableLayout,用于描述表中的列属性。-->
<!--第0列可伸展,第1列可收缩,第2列被隐藏-->
<TextView
android:text="下面是第一个TableLayout,展示全局设置和列属性设置"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="15sp"
android:background="#7f00ffff"/>
<TableLayout
android:id="@+id/table1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="0"
android:shrinkColumns="1"
android:collapseColumns="2"
android:padding="3dp">
<TableRow>
<Button android:text="该列可伸展"/>
<Button android:text="该列可收缩"/>
<Button android:text="我被隐藏了"/>
</TableRow>
<TableRow>
<TextViewandroid:text="我只能向行方向伸展。。"/>
<TextViewandroid:text="我向行方向收缩,但是在列方向扩展,我可以很深深深深深深深深深深深深深深深深深深深深深深深深深深深深深深"/>
</TableRow>
</TableLayout>
<!-- 第2个TableLayout,用于描述表中单元格的属性-->
<!--包括:android:layout_column及android:layout_span-->
<TextView
android:text="下面是第二个TableLayout,展示单元格属性设置"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="15sp"
android:background="#7f00ffff"/>
<TableLayout
android:id="@+id/table2"
属性,a 象里面,们运行程序,截图如下android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="3dp">
<TableRow>
<Button android:text="第0列"/>
<Button android:text="第1列"/>
<Button android:text="第2列"/>
</TableRow>
<TableRow>
<TextViewandroid:text="我被指定在第1列"
android:layout_column="1"/>
</TableRow>
<TableRow>
<TextView
android:text="我可以跨第1列和第2列"
android:layout_column="1"
android:layout_span="2"/>
</TableRow>
</TableLayout>
<!-- 第3个TableLayout,使用可伸展特性,并指定每个控件宽度一致,如1dp-->
<TextView
android:text="下面是第三个TableLayout展示均匀布局"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="15sp"
android:background="#7f00ffff"/>
<TableLayout
android:id="@+id/table4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="*"
android:padding="3dp">
<TableRow>
<Button android:text="刀"android:layout_width="1dp"/>
<Button android:text="刀疤"android:layout_width="1dp"/>
<Button android:text="刀疤鸭"android:layout_width="1dp"/>
</TableRow>
</TableLayout>
</LinearLayout>
在这个布局文件中包括了三个TableLayout,分别用来说明TableLayout的不同的属性,TableLayout包括全局属性,即列属性和单元格属性,列属性调整列的属性,单元格属性可以让用户自己定义单元格。
全局属性及其含义如下表所示:
属性名 | 属性值 |
android:collapseColumns | 设置要隐藏的列。android:collapseColumns="*"隐藏所有列,写具体的数字表示隐藏数字代表的那一列,列从第0列开始。 |
android:stretchColumns | 设置可伸展的列。该列可以向行方向伸展,最多可占据一整行。用法同上。 |
android:shrinkColumns | 设置可收缩的列。当该列子控件的内容太多,已经挤满所在行,那么该子控件的内容将往列方向显示。用法同上。 |
说明:列可以同时具备stretchColumns及shrinkColumns属性,若此,那么当该列的内容很多时,将“多行”显示其内容。(这里不是真正的多行,而是系统根据需要自动调节该行的layout_height)
单元格属性有两个,如下表所示:
表5-11 TableLayout单元格属性表
属性名 | 属性值 |
android:layout_column | 指定该单元格在第几列显示,如android:layout_column="1"该控件显示在第1列。 |
android:layout_span | 指定该单元格占据的列数(未指定时,为1),如android:layout_span="2"该控件占据2列。 |
说明:一个单元格也可以同时具备这两个特性。
我们运行程序,截图如5-49所示:
图5-49 表格布局示意图
如图所示,第一个TableLayout展示了三个列属性,隐藏了第2列,收缩第1列以及拉伸第0列。第二个TableLayout展示了列属性,指定了TextView所占的列值以及列数。第三个TableLayout展示了如何借助全局属性以及单元格属性实现单元格等宽设置,只需要设置全部列可拉伸并且单元格的宽度一样即可,即设置android:stretchColumns="*"以及android:layout_width="1dp"。