购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.3 UI布局

3.3.1 布局基类(ViewGroup)

前面讲到,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:绝对布局

3.3.2 线性布局(LinearLayout)

线性布局(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>

在模拟器上的运行效果图:

3.3.3 帧布局(FrameLayout)

帧布局(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>

在模拟器上运行效果:

3.3.4 相对布局(RelativeLayout)

相对布局(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>

在模拟器上运行效果:

3.3.5 表格布局(TableLayout)

表格布局(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>

在模拟器上运行效果:

3.3.6 绝对布局(AbsoluteLayout)

绝对布局(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>

在模拟器上运行效果如下:

lViX/pFdmvQxERmDwf81u6x3vhpBxp0Iv6uGvLFNGNCffD7USA6dcnNf40/dkYNl

点击中间区域
呼出菜单
上一章
目录
下一章
×