前面讲到,Android UI组件均以View为基类,而其中有一个特别的类ViewGroup类,为其它UI组件的容器。而作为一个View容器,它不仅承装了UI组件,还可以定义其UI组件在ViewGroup内的分布显示效果。
ViewGroup容器控制其内的UI组件分布依赖于它的两个内部类:ViewGroup.LayoutParams、ViewGroup.MarginLayoutParams。接下来分别介绍这两个内部类的作用。
ViewGroup.LayoutParams提供了两个XML属性设定UI组件在ViewGroup容器内的大小:
· android:layout_height:指定该UI组件的基本高度。
· android:layout_width:指定该UI组件的基本宽度。
ViewGroup.LayoutParams为开发人员定义了三个整形的静态常量,用于指定其高度与宽度:
· FILL_PARENT:指定UI组件的高度、宽度与父容器一致(Android 2.2之后就已经弃用)。
· MATCH_PARENT:指定UI组件的高度、宽度匹配父窗口(Android 2.2之后推荐使用)。
· WRAP_CONTENT:包裹内容,其高度、宽度受UI组件展示内容所影响。
而ViewGroup.MarginLayoutParams用于控制其UI组件在其容器内,距离其各个方向的边距。它一样定义了一些XML属性用于设定UI组件距离容器的边距:
· android:layout_marginTop:UI组件距离父容器上边框的距离。
· android:layout_marginBottom:UI组件距离父容器下边框的距离。
· android:layout_marginLeft:UI组件距离父容器左边框的距离。
· android:layout_marginRight:UI组件距离父容器右边框的距离。
对于View的尺寸,Android提供了三种单位供开发人员选择使用:
· px:像素。
· dp:dpi,表示屏幕实际的像素。
· sp:与比例无关的像素,与dp类似。
虽然Android提供了三种尺寸单位,但是因为Android的开源导致了运行Android系统的设备的屏幕差异太大,所以一般无特别需求,推荐使用dp作为View的尺寸单位。
ViewGroup是一个抽象类,无法直接使用,但是它旗下还有一些子类可供我们选择使用。为了适应各种界面风格,Android提供了五个ViewGroup的子类,利用这五种布局,基本上可以在任何设备上随心所欲的摆放任何UI组件,接下来对这五种布局对象分别讲解。
· LinearLayout:线性布局。
· FrameLayout:帧布局。
· RelativeLayout:相对布局。
· TableLayout:表格布局。
· AbsoluteLayout:绝对布局
线性布局(LinearLayout)是最常用的布局方式,在XML布局文件中使用<LinearLayout/>标签标记。LinearLayout会将其容器内的所有UI组件一个挨着一个进行排序,但是LinearLayout是不会进行换行的,也就是说,当排序的UI组件已经超出了屏幕显示的范围之后,余下的UI组件将不会被显示出来。
LinearLayout有两个重要的XML属性,用于控制LinearLayout内UI组件摆放的规则,Android也提供了对应的方法进行操控:
XML属性 | 相关方法 | 说明 |
android:gravity | setGravity(int) | 设置LinearLayout内UI组件的对其方式。 |
android:orientation | setOrientation(int) | 设置LinearLayout内UI组件的排序方式。 |
从提供的相关方法可以看出,其中需要的参数均为int类型,对于android:gravity属性,其设定的参数被以静态常量的形式定义在Gravity类中,一般常用的属性值有:
· top:沿着LinearLayout的顶部对齐。
· bottom:沿着LinearLayout的底部对齐。
· left:沿着LinearLayout的左边框对齐。
· right:沿着LinearLayout的右边框对齐。
· center_vertical:在LinearLayout中垂直居中。
· center_horizontal:在LinearLayout中水平居中。
· fill_vertical:在LinearLayout中垂直填满。
· fill_horizontal:在LinearLayout中水平填满。
还有一些特殊的属性值定义在Gravity中,这里不再一一介绍了,上面列举的android:gravity的属性值并不冲突,Android中也规定可以混合使用,只需要使用"|"符号分割即可,注意"|"符号两边不允许有空格。
对于android:orientation属性来设定LinearLayout的排序方向,其属性值被定义在LinearLayout自身中,并以整形的静态常量的形式定义,可以直接使用,它有两个属性值供我们选择:
· horizontal:水平排序。
· vertical:垂直排序,默认值。
示例:讲解线性布局的使用,在其内定义几个按钮控件,并控制其布局。
代码清单:\codes\03\3.3\LinearLayoutDemo\res\layout\activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom" android:orientation="horizontal" tools:context=".MainActivity" > <!-- 定义一个线性布局 设定其内UI组件沿着父容器底部对齐 并横向排列 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="button" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="button" /> <!-- 定义这个控件顶部对齐 --> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" android:layout_weight="1" android:text="button" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="button" /> </LinearLayout>
在模拟器上的运行效果图:
帧布局(FrameLayout)是最简单的布局方式,在XML布局文件中使用< FrameLayout />标签标记。它会为FrameLayout中定义的UI组件创建一个空白的帧,每个UI组件都是一个独立的帧,这些帧会根据android:gravity属性进行自动对齐。FrameLayout有一个特点,因为在FrameLayout中的UI组件都是一个独立的帧,所以后定义的UI组件会遮挡先声明的UI组件。
示例:使用帧布局模拟彩虹效果。
代码清单:\codes\03\3.3\FrameLayoutDemo\res\layout\ activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#8b00ff" android:height="50px" android:width="210px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#0000ff" android:height="50px" android:width="180px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#007fff" android:height="50px" android:width="150px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00ff00" android:height="50px" android:width="120px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffff00" android:height="50px" android:width="90px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffa500" android:height="50px" android:width="60px" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0000" android:height="50px" android:width="30px" /> </FrameLayout>
在模拟器上运行效果:
相对布局(RelativeLayout)在XML布局文件中使用<RelativeLayout/>标签标记,其内部的UI组件的位置,通过其它UI组件和父容器来决定。也就是说,使用RelativeLayout进行UI布局,其中的每个UI组件的位置均依赖于其它UI组件或父容器边框的位置。
RelativeLayout控制其内部的UI组件的位置会通过其它UI组件确定,所以RelativeLayout布局内部的UI组件会被赋予一些特殊的XML属性,使用这些属性设定布局的位置依赖于那个UI组件,通过UI组件的id指定,下面介绍一些常用的属性:
· android:layout_above:设置该UI组件位于给定ID组件的上方。
· android:layout_below:设置该UI组件位于给定ID组件的下方。
· android:layout_toRightOf:设置该UI组件位于给定ID组件的右侧。
· android:layout_toLeftOf:设置该UI组件位于给定ID组件的左侧。
· android:layout_alignTop:设置该UI组件与给定ID组件的上边界对齐。
· android:layout_alignBottom:设置该UI组件与给定ID组件的下边界对齐。
· android:layout_alignRight:设置该UI组件与给定ID组件的右边界对齐。
· android:layout_alignLeft:设置该UI组件与给定ID组件的左边界对齐。
示例:使用相对布局,根据中间UI组件的位置实现梅花效果。
代码清单:\codes\03\3.3\RelativeLayoutDemo\res\layout\ activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:id="@+id/view1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="中" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@id/view1" android:layout_alignLeft="@id/view1" android:text="上" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/view1" android:layout_below="@id/view1" android:text="下" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/view1" android:layout_toLeftOf="@id/view1" android:text="左" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/view1" android:layout_toRightOf="@id/view1" android:text="右" /> </RelativeLayout>
在模拟器上运行效果:
表格布局(TableLayout)在XML布局文件中使用<TbaleLayout/>标签标记,它采用行、列的形式来管理其内的UI组件,在TableLayout内部,行数和列数是没有明确声明的,根据其内的UI组件来指定行数和列数。
对于同一行包含多个UI组件的情况,可以在<TableLayout/>标签内,使用<TableRow/>标签对同行的UI组件进行包裹。
TableLayout的布局效果类似于表格的形式,所以默认情况下其中列的宽度由该列中最宽的那个单元格决定,而整个表格的宽度为父容器的宽度。
TableLayout整个布局的宽度受设备屏幕宽度的限制,Android为TableLayout特别提供了几个属性用于更好的设定列的宽度:
· android:collapseColumns:设置需要被隐藏的列的序号。
· android:shrinkColumns:设置允许被收缩的列的序号。
· android:stretchColumns:设置允许被拉伸的列的序号。
上面的三个TableLayout属性设置列的序号从0开始,多个列序号使用","分割。
示例:使用TableLayout进行布局。
代码清单:\codes\03\3.3\TableLayoutDemo\res\layout\activity_main.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:collapseColumns="1" android:stretchColumns="3" tools:context=".MainActivity" > <!-- 设定 第二列隐藏 第四列拉伸 --> <TableRow android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button3" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button4" /> </TableRow> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#00ffff" /> </TableLayout>
在模拟器上运行效果:
绝对布局(AbsoluteLayout)在XML布局文件中使用<AbsoluteLayout/>标签标记,它不提供任何的布局控制,仅通过UI组件在AbsoluteLayout内部的坐标来控制位置。
为了指定AbsoluteLayout的坐标,Android提供了两个XML属性来设定其坐标:
· android:Layout_x:该UI组件在容器内的X轴坐标。
· android:Layout_y:该UI组件在容器内的Y轴坐标。
AbsoluteLayout并不是常用的布局方式,它依赖于父容器内部的坐标,对于Android这样开源的平台,设备的参数并不统一,所以直接指定UI组件在父容器内的坐标,很容易导致不同设备上运行的效果不一致。现在AbsoluteLayout基本上已经弃用了,在实际开发中也不推荐使用,这里仅对其进行一下简单的讲解。
示例:使用绝对布局实现一个登录界面。
代码清单:\codes\03\3.3\AbsoluteLayoutDemo\res\layout\activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="84dp" android:layout_y="20dp" android:ems="10" /> <EditText android:id="@+id/EditText01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="84dp" android:layout_y="66dp" android:ems="10" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="214dp" android:layout_y="113dp" android:text="重置" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="130dp" android:layout_y="113dp" android:text="登录" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="33dp" android:layout_y="36dp" android:text="用户名" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_x="48dp" android:layout_y="80dp" android:text="密码" /> </AbsoluteLayout>
在模拟器上运行效果如下: