
3.1 Android五大布局管理器
Android的界面是由布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦。组件按照布局的要求依次排列,就组成了用户所看见的界面。通过使用布局管理器,Android应用的界面组件可在不同分辨率的手机上得到良好的控制。因此通常推荐使用布局管理器来管理组件的分布、大小,而不是设置组件的位置和大小。如果在程序中设置了组件的大小和位置,那么这个应用一般只能运行于特定的分辨率的手机,不能做到手机自适应。而Android布局管理器可以根据运行的手机来调整组件的大小与位置,我们只需为容器选择合适的布局管理器。
Android的五大布局分别是LinearLayout(线性布局)、FrameLayout(单帧布局)、RelativeLayout(相对布局)、AbsoluteLayout(绝对布局)和TableLayout(表格布局)。
3.1.1 线性布局
线性布局管理器在XML文件中为一个LinearLayout标签,在该标签下的子标签所代表的组件将会按照从左到右或从上到下的顺序依次排列起来。LinearLayout通过设置android:orientation属性来控制容器里各组件的排列方向,可横向排列,亦可纵向排列。
提示:当组件太多时,排列到手机屏幕的尽头时,Android线性布局不会自动将余下的组件换到下一行显示,剩下的组件将看不到。
LinearLayout中的子元素有一个重要的属性是android:layout_weight,它用于描述该子元素在该LinearLayout中的权重。如一行只有一个文本框,那么该属性的默认值就为0。如果一行中有两个等长的文本框,那么它们该属性的值可以同为1。如果想让同一行的两个文本框其中的一个长占三分之二,另一个长占三分之一,那么它们该属性的值就为1和2。总之记住,android:layout_weight的数值越小,权重越高。
如下XML代码文件定义了一个线性布局。

上面的布局文件定义了一个简单的线性布局,布局中的三个按钮从上到下垂直排列,并且整体底部居中。运行上面的程序,可以看到如图3.1所示的界面。

图3.1 垂直排列,底部居中
如果把上面代码文件中的android:gravity的属性值改为center,则运行结果变为如图3.2所示。
如果要将这三个按钮设置成从左到右顺序排列,那么只要将android:orientation属性值改为horizontal即可。运行结果如图3.3所示。

图3.2 垂直排列,整体居中

图3.3 横向排列,整体居中
3.1.2 表格布局
表格布局在XML代码文件中用一个TableLayout表示,可以在一个Activity中添加多行,每一行又可以设置多个列,横竖交叉,形成表格,所以叫表格布局。
表格布局用添加一个TableRow标签来表示新增加一行,然后在这个TableRow中添加一个组件,表示该TableRow新增了一列。列的宽度由该列中最宽的那个单元格决定,整个TableLayout的宽度则取决于父容器的宽度(如手机屏幕宽度)。
如果直接向TableLayout添加组件,那么这个组件就直接占用一行。
在表格布局中,可以为单元格设置如下属性。
android:collapseColumns="1",隐藏该TableLayout里的TableRow的列1,即第2列(从0开始算起),若有多列要隐藏,则列数之间用“,”隔开。
android:shrinkColumns="1",将TableLayout里的TableRow的列1设置收缩,即第2列(从0开始算起),若有多列要收缩,则列数之间用“,”隔开。
android:stretchColumns="1",将TableLayout里的TableRow的列1设置伸张,即第2列(从0开始算起),若有多列要伸张,则列数之间用“,”隔开。
注意:TableLayout的行数由开发人员制定,即有多少个TableRow对象(或view控件),就有多少行。列的宽度:由该列中最宽的单元格决定,整个表格布局的宽度取决于父容器的宽度(默认是占满父容器本身)。如第一个TableRow含2个控件,第二个TableRow含3个控件,那么该TableLayout的列数为3。
如下XML代码文件定义了一个TableLayout。运行结果如图3.4所示。



图3.4 定义TableLayout
运行结果如图3.4所示。
3.1.3 相对布局
Android相对布局在XML文件的元素为RealativeLayout,在相对布局中,一个控件的位置决定于它和其他控件的关系。这样做的好处是比较灵活,缺点是比较复杂。接下来将相对布局常用的属性分成四组进行讲解。
表3.1给出了四个属性设置控件之间的关系和位置。
表3.1 位置属性

上面四个属性并没有设置各个控件之间是否对齐。例如使用android:layout_below属性将B控件置于A控件之下,那么可能出现的情况是B控件确实在A控件之下,但B控件跟A控件并没有对齐,另一种情况是B控件在A控件之下的同时两控件对齐。
如下定义的XML界面文件,将B控件置于A控件之下,但两者并没有对齐。

运行效果如图3.5所示。
将上面代码文件中的android:layout_alignParentRight="true"去掉,B控件与A控件将对齐,运行效果如图3.6所示。

图3.5 B控件与A控件没对齐

图3.6 B控件与A控件对齐
如表3.2所示的五个属性,设置的是控件与控件之间的对齐方式。
表3.2 控件之间对齐方式属性

给代码文件:codes\O3\3.1\RelativeLayoutDemo\res\layout\activity_main.xml中的B控件加上android:layout_alignRight="@id/btn_A"这样一句代码,即可控制A控件跟B控件的右边缘对齐。运行效果如图3.7所示。

图3.7 B控件根A控件的右边边缘对齐
表3.3给出了四个属性设置控件与父控件之间对齐的方式。
表3.3 控件与父控件之间对齐的方式属性

如下面的XML代码文件,将A控件与B控件上下置放,并且B控件右边边缘与父控件对齐。


图3.8 B控件右边边缘跟父控件对齐
运行效果如图3.8所示。
表3.4给出了三个属性控制控件的方向。
表3.4 控件方向属性

下面的XML代码文件中,B控件在父控件上下左右方向居中。

运行效果如图3.9所示。

图3.9 B控件在父控件居中
3.1.4 绝对布局
绝对布局在Android中用AbsoluteLayout表示。绝对布局中的组件大小需要开发人员自己来控制,甚至组件的位置都需要开发人员通过坐标来控制。
在相对布局中,通过设置每个控件的layout_x以及layout_y属性来设置控件的x坐标和y坐标,以此来控制控件的位置。
注意:使用绝对布局的方法在直接拖控件的时候显得比较方便,但是不利于程序的后期调整,而且也不能做到界面的自适应性,很难做到兼顾不同手机的屏幕大小以及分辨率。
如下XML代码文件中,用绝对布局定义了一个登录界面。

运行效果如图3.10所示。

图3.10 绝对布局
上面在设置组件的x坐标、y坐标中用了android:layout_x="20dip"这样的语句,dip是一个距离单位。Android支持如下常用的距离单位。
px:像素,每个像素对应屏幕中的一个点。
dip或dp:设备独立像素,一种基于屏幕密度的抽象单位。1dip=1px,但随着屏幕密度的改变,dip与px的换算会发生改变。
sp:比例像素,主要处理字体的大小。
3.1.5 帧布局
FrameLayout帧布局在屏幕上开辟出一块区域,在这块区域中可以添加多个子控件,但是所有的子控件都被对齐到屏幕的左上角。帧布局的大小由子控件中尺寸最大的那个子控件来决定。如果子控件一样大,那么同一时刻只能看到最上面的子控件。
在帧布局中,子控件是通过栈来绘制的,所以后添加的子控件会被控制在上层。
如下XML代码文件中,在一个帧布局中定义了三个线性布局,层层相叠。运行效果如图3.11所示。

运行效果如图3.11所示。

图3.11 帧布局