【风马一族_Android】第4章Android常用基本控件

时间:2022-06-21 06:28:17

第4章Android常用基本控件

控件是Android用户界面中的一个个组成元素,在介绍它们之前,读者必须了解所有控件的父类View(视图),它好比一个盛放控件的容器。

4.1View类概述

对于一个Android应用来说,android.app.Activity类实例是一个最基本的功能单元。一个Activity实例可以做很多的事情,但是它本身无法显示在屏幕上,而是借助于View和ViewGroup,它们是Android平台上最基本的两个用户界面表达单元。

4.1.1 关于View

View对象是一个数据体,它的属性存储了用于屏幕上一块矩形区域的布局参数及内容,并负责这块它所辖的矩形区域之中所有测量、布局、焦点转换、卷动以及按键/触摸手势的处理。作为一个用户界面对象,View同时也担任着用户交互关键点以及交互事件接受者的角色。View来自android.view.View类。在屏幕上,每个View的子类对象都是android.view.View类的一个实例,所有在Activity中要用到可视化的窗体控件,就必须在该类定义的代码文件前部加上“import android.view.View;”。

View类是所有屏幕表达单元的基类。View类的所有属性,以及在View类中定义的所有成员方法,其子类都全部继承。表4-1 描述了View类常用的属性及其对应方法。

表4-1 View类常用的属性及对应方法说明
 属性  方法  描述
 android:background setBackgroundResource(int)  设置背景
 android:clickable setClickable(boolean)  设置View是否响应单击事件
 android:visible setVisible(int)  控制View的可见性
 android:focusable setFocusable(boolean)  控制View是否可以获取焦点
 android:id setId(int)  为View设置标识符,可通过findViewById()方法获取
 android:longClickable setLongClickable(boolean)  设置View是否响应长单击事件
 android:saveEnabled setSaveEnabled(boolean)  如果未作设置,当View被冻结时将不会保存其状态
 android:layout_width    设置宽度,可以使用数字

match_parent表示填充所有空白,

wrap_content表示按对象上的文字的宽度不同而确定显示对象的宽度

 android:layout_height    设置高度,属性值同android: layout_width
 android:gravity  

设置控件内部显示对象的位置对齐布局方式

gravity是一个很有用的属性,它用来设置线性布局内显示对象的对齐方式。gravity可取的值及其说明如表4-2所示

表4-2 gravity可取的属性值及说明
属性值 说明
top 不改变显示对象的大小,对齐到窗口顶部
bottom 不改变显示对象的大小,对齐到窗口底部
left 不改变显示对象的大小,对齐到窗口左侧
right 不改变显示对象的大小,对齐到窗口右侧
center_vertical 不改变显示对象的大小,对齐到容器纵向*位置
center_horizontal 不改变显示对象的大小,对齐到容器横向*位置
center 不改变显示对象的大小,对齐到容器*位置
fill_vertical 若有可能,纵向拉伸以填满容器
fill_horizontal 若有可能,横向拉伸以填满容器
fill 若有可能,纵向、横向同时拉伸以填满容器

4.1.2 关于ViewGroup

ViewGroup是一个特殊的View类,它继承于android.view.View,是View类的子类。ViewGroup是充当其他控件的容器,在其内可以有View对象和ViewGroup对象,它的功能就是装载和管理下一层的View对象和ViewGroup对象。确切地说,它是所有容器类的基类。

View的布局显示方式直接影响用户界面,准确地说是一个ViewGroup中包含的一些View对象是如何布局的。在ViewGroup中,定义了一个嵌套类ViewGroup.LayoutParams。这个类定义了一个显示对象的位置、大小等属性,View通过LayoutParams中的这些属性值来告诉Android系统,它们将如何放置。这就是布局类。

在Android中,布局类通常都在布局的XML文件中描述,而很少在Java代码中动态定义。如果使用Java代码定义布局,那么在代码文件的前部必须加上“import android.view. ViewGroup;”。

4.2 常见布局

布局(Layout)是ViewGroup的子类,为视图控件提供排列结构。Android提供了一些预定义的视图组,其中包括FrameLayout,LinearLayout,TableLayout,RelativeLayout,AbsoluteLayout。每个都为定义子视图和布局结构提供了一套独特的布局参数。下面分别介绍。

4.2.1 帧布局

帧布局(FrameLayout)是最简单的一个布局对象。它里面只显示一个View对象。Android屏幕元素中所有的显示对象都将会固定在屏幕的左上角,不能指定位置。如果在帧布局中有多个显示对象,那么后一个将会直接在前一个之上进行覆盖显示,把前一个部分或全部遮住。当然,如果后一个显示对象是透明的,则前一个对象会显现出来。使用帧布局设计的效果如图4-1所示。

图4-1 帧布局的显示效果

 <?xml version="1.0" encoding="utf-8"?>
<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="cn.com.sgmsc.Frame.Activity_FrameLayout"> <!--
这个帧布局中放入三个按钮,按钮间的位置中叠加式的,处于最底部位置是从先放入的组件开始的,
处于最顶部位置的是最后放入的组件,其它部件的位置以此类推
从界面显示的效果可知
-->
<!--红色-->
<Button
android:layout_width="350sp"
android:layout_height="350sp"
android:layout_gravity="center"
android:background="@color/colorAccent"/> <!--蓝色-->
<Button
android:layout_width="250sp"
android:layout_height="250sp"
android:layout_gravity="center"
android:background="@color/colorPrimary"/> <!--淡青铜色-->
<Button
android:layout_width="150sp"
android:layout_height="150sp"
android:layout_gravity="center"
android:background="@color/colorPrimaryDark"/>
</FrameLayout>

main.xml

4.2.2线性布局

线性布局(LinearLayout)是最常用的布局方式。它以单一方向对其中的View对象进行排列显示,如果以垂直排列显示,则屏幕布局中将只有一列; 如果以水平排列显示,则屏幕布局中将只有一行。对于多个显示对象,线性布局保持它们之间的间隔以及互相对齐。使用线性布局设计的效果如图4-2和图4-3所示。

在进行线性布局中,可以通过设置其属性值来改变排列在其中的显示对象的显示效果。常用的属性如表4-2所示。

图42横向线性布局显示效果

图43纵向线性布局显示的效果

表42线性布局特有属性说明
属性 说明
android: orientation 设置线性布局的排列方向。Horizontal表示横向,vertical表示纵向
android: layout_weight 设置线性布局内部多个显示对象的重要度赋值,按比例为它们划分空间

在线性布局中,如果有多个View对象,那么所有的对象都有一个layout_weight值,默认为0,其意思是按显示对象的原来大小显示在屏幕上。如果layout_weight值大于0,则将本线性布局的父视图中的可用空间分割,分割大小具体取决于每一个显示对象的layout_weight值。例如,如果在水平的线性布局中有一个文本标签和两个文本编辑对象,如果该文本标签并无指定layout_weight值,那么它将占据需要提供的最少空间; 如果两个文本编辑对象每一个的layout_weight值都设置为1,则两者平分布局区域的剩余宽度,因为这里声明两者的重要度相等; 如果两个文本编辑对象中第一个layout_weight值设置为1,而第二个的值设置为2,于是,第一个占剩余宽度的三分之二,而第二个占三分之一的宽度,因为layout_weight的数值越小,越重要。可见,当线性布局中有多个显示对象时,layout_weight属性很重要,它可以避免在一个大屏幕中,一串小对象挤成一堆的情况。

【案例4.1】设计出如图4-2所示的布局文件。

【说明】图4-2中有5个按钮,它们以横向的线性排列方式显示在屏幕的顶部。因此在布局文件中要使用layout_weight属性且值都相同。

【代码】在AndroidStudio导入Activity_LinearLayout项目(可以从清华大学出版社为本书提供的下载资源的源代码中获得)。打开res/layout目录下的main.xml文件,代码如下所示。

 <?xml version="1.0" encoding="utf-8"?>
<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:orientation="horizontal"
tools:context="cn.com.sgmsc.Line.Activity_LineLayoutActivity"> <!--
id="@+id/自己取的名字“ 所取的名字,必须是唯一,最好存在某种意义,
id="@id/取别人的名字” 例如:在相对布局中,就是获取其它的组件id,来识别相应组件的位置
组件、布局都需要其高度/宽度 wrap_contentr的大小是根据组件中文本大小及数量来决定
match_parent的大小是尽可能的占领空白空间
text="输入所要的文本内容"
layout_weight:表示权重,在线性布局中,权重的大小影响了组件在布局中显示的大及组件间的关系
android:onClick="onClick" 设置该组件在业务逻辑中可以进行事件处理,这一步骤让组件在
Activity_LineLayoutActivity.java无需定义组件,就可以直接进行业务逻辑
还有其它参数,没有使用,强烈希望读者可以尝试。
-->
<Button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button1"
android:onClick="onClick"
android:layout_weight="1" />
<Button android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button2"
android:onClick="onClick"
android:layout_weight="1" />
<Button android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button3"
android:onClick="onClick"
android:layout_weight="1" />
<Button android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button4"
android:onClick="onClick"
android:layout_weight="1" />
<Button android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button5"
android:onClick="onClick"
android:layout_weight="1" />
</LinearLayout>

main.xml

(1) 第2~51行声明一个线性布局。其中,线性布局的属性定义在第5~7行,第3、4、8行是每个Android布局文件必有的; 第5~6行设置线性布局的宽和高属性值,值都是match_parent,即充满容器的宽和高; 第5行设置线性布局的方向是horizontal,即是横向的。

(2) 第21~26行、第27~32行、第33~38行、第39~44行、第45~50行分别声明了5个按钮,每个按钮中的文本都比较长,如果不设置layout_weight的值,在屏幕的一行中是显示不下所有5个按钮的。

(3) layout_weight权值在线性布局中,是相当常用的,读者需要反复对不同组件进行设置不同权值,来理解它。

思考一下:

如果将每个Button的属性“android:layout_weight=1”都删掉,会出现什么样的显示效果?

图4-4 嵌套线性布局显示的效果

线性布局允许嵌套。在开发中,往往在一个横向的线性布局里嵌套一个纵向的线性布局,或在一个纵向的线性布局里嵌套一个横向的线性布局。这是非常常用的技巧。

【案例4.2】设计出如图4-4所示的布局文件。

【说明】从图4-4中可以看到,这个布局应该是: 外层是一个纵向的线性布局,并且上下两部分的高度是不等比的。内层是一个横向的线性布局,并且是等分的两部分。有5个按钮,它们以横向的线性排列方式显示在屏幕的顶部。因此在布局文件中要使用layout_weight属性。

【代码】在AndroidStudio中导入Activity_NestLineLayout项目(建议读者使用本教材的源代码,并尝试编程)。打开res/layout目录下的main.xml文件,代码如下所示。

 <?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
tools:context="cn.com.sgmsc.NLine.Activity_NestLineLayout"> <!--
线性布局嵌套着两个线性布局,上面的线性布局加入一个文本
下面的线性布局加入两个文本,分别显示红色、绿色背景
android:layout_weight="2" 权值在线性布局中是常用参数
-->
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
<TextView
android:text="这个的权值为2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"> <TextView
android:text="红"
android:textSize="96sp"
android:gravity="center_horizontal"
android:background="#aa0000"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"/>
<TextView
android:text="绿"
android:textSize="96sp"
android:gravity="center_horizontal"
android:background="#00aa00"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>

main.xml

(1) 第2~48行声明的是外层线性布局,从第7行知此线性布局的方向是vertical,即是纵向的。

(2) 第15~24行声明的是上面的内层线性布局。为了与下面的高度不一致,设置此线性布局的layout_weight属性值为2。由于此线性布局内只有一个<TextView>控件,所以此线性布局的方向可为横向,也可为纵向,这里设置的是纵向。

(3) 第25~47行声明的是下面的内层线性布局。此线性布局内有两个<TextView>控件,所有设置此线性布局的layout_weight属性值为1; 设置此线性布局的方向是horizontal,即是横向的。

4.2.3表格布局

表格布局(TableLayout)是线性布局的特殊类。以拥有任意行列的表格对View对象进行布局,每个单元格内只显示一个View对象,但单元格的边框线不可见。表格布局类每一行为一个TableRow对象,在TableRow中可以添加显示对象,每添加一个显示对象为一列。

在表格布局中,一个列的宽度由该列中最宽的那个单元格确定,而表格的宽度则是由父容器确定。布局中可以有空的单元格,也可以像HTML文件一样,一个单元格可以跨越多个列。

TableLayout继承自LinearLayout类,它继承了线性布局所拥有的属性和方法,但表格布局还有它特有的,为列设置有属性和方法。表44是对表格布局列的常用属性的描述。

表4-4表格布局列的常用属性说明

属性 说明
android:collapseColumns 设置指定列为Collapsed,列号从0开始计算。如果列被标识为Collapsed,则该列将会被隐藏
android:shrinkColumns 设置指定列为Shrinkable,列号从0开始计算。如果列被标识为Shrinkable,则该列的宽度可以进行收缩,以使表格能够适应其父容器的大小
android:stretchColumns 设置指定列为Stretchable,列号从0开始计算。如果列被标识为Stretchable,则该列的宽度可以进行拉伸,以填满表格中空闲的空间

注意,一个列可以同时具有Shrinkable和Stretchable属性,在这种情况下,该列的宽度将可以任意地进行收缩或拉伸以适应父容器。

【案例4.3】设计一个三行三列的表格布局,其中第一行前两列分别放两个按钮,第二行后两列分别放两个按钮,第三行第三列放一个按钮。

【说明】这个表格布局每一行的显示对象的位置都不相同,在布局文件中需要使用TableRow类来逐行定义。另外,这里没有对每个按钮的宽度作要求,在此默认是等宽的。

【代码】在AndroidStudio中导入Activity_TableLayout项目(可以从本教材的源代码中获得)。打开res/layout目录下的main.xml文件,代码如下所示。

 <?xml version="1.0" encoding="utf-8"?>
<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:stretchColumns="0,1,2"
tools:context=".Activity_TableLayoutActivity"> <!--
android:stretchColumns 设置可伸展的列。该列可以向行方向伸展,最多可占据一整行。
android:shrinkColumns 设置可收缩的列。当该列子控件的内容太多,已经挤满所在行,那么该子控件的内容将往列方向显示。
android:collapseColumns 设置要隐藏的列 TableLayout:表格布局
TableRow : 行,必需给
<TableRow> 所设的组件,都放在同一行
设置组件
</TableRow>
--> <TableRow><!-- row1 -->
<Button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1"
android:onClick="onClick"
android:layout_column="0" />
<Button android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮2"
android:onClick="onClick"
android:layout_column="1" />
</TableRow>
<TableRow><!-- row2 -->
<Button android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮3"
android:onClick="onClick"
android:layout_column="1" />
<Button android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮4"
android:onClick="onClick"
android:layout_column="1" />
</TableRow>
<TableRow ><!-- row3 -->
<Button android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮5"
android:onClick="onClick"
android:layout_column="2" />
</TableRow>
</TableLayout>

main.xml

(1) 第2~42行声明的是表格布局。其中第5行定义了该表格是三列的,且是可收缩的,这样,布局按照父容器的宽度平分三列宽度,如果每列中的显示对象超出了单元格的宽度就自动收缩至单元格宽度。列号从0开始计算。

(2) 第6~19行声明了表格的第一行。其中有两个按钮<Button>标签,尽管每个按钮的layout_width和layout_height值都是wrap_content,即以文本的宽度、高度为按钮的尺寸,但是由于在<TableLayout>中设置属性“android:shrinkColumns="0,1,2"”,所以最终三列还是以三等份来平分父容器的宽度。

(3) 第11行表示在此行第一列显示按钮1,第17行表示在此行第二列显示按钮2。

(4) 第20~33行声明了表格的第二行,其中定义了两个<Button>标签。

图4-5 三行三列表格布局的显示效果

(5) 第25行表示在此行第二列显示按钮3,第31行表示在此行第二列之后添加一列(即第三列)显示按钮4。

(6) 第34~41行声明了表格的第三行,其中定义了一个<Button>标签,并定义在第三列显示。

【运行结果】在Eclipse中启动Android模拟器,然后运行Activity_TableLayout项目。运行结果如图45所示。

4.2.4相对布局

相对布局(RelativeLayout)允许通过指定View对象相对于其他显示对象或父级对象的相对位置来布局。如一个按钮可以放于另一个按钮的右边,或者可以放在布局管理器的*等。注意,如果对象A的位置是相对于对象B来决定的,那么必须先定义了对象B,然后才能定义对象A。

在进行相对布局时用到的属性较多,下面按其属性值的归类分别进行介绍。

属性值为true或false的属性如表45所示。

表45相对布局中取值为true或false的属性及说明

属性说明

android:layout_centerHorizontal当前显示对象位于父控件的横向中间位置

android:layout_centerVertical当前显示对象位于父控件的纵向中间位置

android: layout_centerInParent当前显示对象位于父控件的*位置

android: layout_alignParentBottom当前显示对象底端与父控件的底端对齐

android: layout_alignParentLeft当前显示对象左侧与父控件的左侧对齐

android: layout_alignParentRight当前显示对象右侧与父控件的右侧对齐

android: layout_alignParentTop当前显示对象顶端与父控件的顶端对齐

android: layout_alignWithParentIfMissing参照对象不存在或不可见时参照父控件

属性值为其他控件的id的属性如表46所示。

表46相对布局中取值为其他控件id的属性及说明

属性说明

android:layout_toRightOf使当前显示对象位于给出id控件的右侧

android:layout_toLeftOf使当前显示对象位于给出id控件的左侧

android: layout_above使当前显示对象位于给出id控件的上方

android: layout_below使当前显示对象位于给出id控件的下方

android: layout_alignTop使当前显示对象的上边界与给出id控件的上边界对齐

android: layout_alignBottom使当前显示对象的下边界与给出id控件的下边界对齐

android: layout_alignLeft使当前显示对象的左边界与给出id控件的左边界对齐

android: layout_alignRight使当前显示对象的右边界与给出id控件的右边界对齐

属性值为像素单位的属性如表47所示。

表47相对布局中取值为像素单位的属性及说明

属性说明

android:layout_marginLeft当前显示对象左侧的留白

android:layout_marginRight当前显示对象右侧的留白

android: layout_marginTop当前显示对象上方的留白

android: layout_marginBottom当前显示对象下方的留白

注意,在进行相对布局时要避免循环依赖。例如,在相对布局中设置了父容器的排列方式为WRAP_CONTENT,即表示它将以容器内的显示子对象的大小为尺寸,如果此时将其子对象设置为ALIGN_PARENT_BOTTOM,即表示它将与父容器的底部对齐。这就出现了循环依赖的排列,因此造成子控件与父控件相互依赖和参照的错误。

【案例4.4】试使用相对布局来设计如图46所示的界面效果。

图46一个简单的信息录入框界面

【说明】通常可以使用嵌套的线性布局或者使用表格布局来实现如图46所示的用户界面,但在此需要使用相对布局实现。先来分析一下界面中各个对象的位置,最上方是一个与屏幕左对齐的文字串,可使用<TextView>控件; 它的下方是一个可输入的编辑框,并充满整个屏幕宽度,可使用<EditText>控件; 它的下方是两个并排的按钮,并且是与屏幕右对齐的。当设计它们的显示位置时,一定要找准参照对象。

【代码】在Eclipse中导入Activity_RelativeLayout项目(可以从本教材的源代码中获得)。打开res/layout目录下的main.xml文件,代码如下所示。

1?xml version="1.0" encoding="utf-8"?

2RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

3android:layout_width="fill_parent"

4android:layout_height="fill_parent"

5

6TextView

7android:id="@+id/label"

8android:layout_width="fill_parent"

9android:layout_height="wrap_content"

10android:text="Type here:"

11/

12EditText

13android:id="@+id/entry"

14android:layout_width="fill_parent"

15android:layout_height="wrap_content"

16android:background="@android:drawable/editbox_background"

17android:layout_below="@id/label"/

18Button

19android:id="@+id/ok"

20android:layout_width="wrap_content"

21android:layout_height="wrap_content"

22android:layout_below="@id/entry"

23android:layout_alignParentRight="true"

24android:layout_marginLeft="10dip"

25android:text="OK" /

26Button

27android:layout_width="wrap_content"

28android:layout_height="wrap_content"

29android:layout_toLeftOf="@id/ok"

30android:layout_alignTop="@id/ok"

31android:text="Cancel" /

32

33/RelativeLayout

(1) 第2~33行声明了一个相对布局,并且这个相对布局的宽度和高度都充满屏幕。

(2) 第6~11行声明了一个<TextView>控件,它的ID为“label”,显示内容为“Type here:”。第8行设置该文本框的宽度是fill_parent,即填满其父容器。第9行设置的高度为wrap_content,即其高度为文本的高度。

(3) 第12~17行声明了一个<EditText>控件,它的ID为“entry”。第17行设置本编辑框的位置,指定它位于ID为“label”的<TextView>控件的下方。

(4) 第18~25行声明了一个<Botton>控件,它的ID为“ok”。第22行设置本按钮的位置,指定它位于ID为“entry”的< EditText >控件的下方; 第23行指定它与父容器的右侧对齐; 第24行指定本按钮的左侧留白为10dip; 按钮上显示的文本为“OK”。

(5) 第26~31行声明了一个<Botton>控件。第29行设置本按钮位于ID为“ok”的按钮控件的左侧,并由第24行知与“ok”按钮控件的间距为10dip; 第30行指定它与OK按钮控件的上边界对齐; 按钮上显示的文本为“Cancel”。

4.2.5绝对布局

绝对布局(AbsoluteLayout)允许以坐标的方式,指定View对象的具体位置,左上角的坐标为(0, 0),向下及向右,坐标值变大。这种布局管理器由于显示对象的位置定死了,所以在不同的设备上,有可能会出现最终的显示效果不一致的情况。

由于每一个显示对象都是通过计算其坐标来定位和布局的,与周围的其他控件和父容器无关,所以绝对布局是一种用起来比较费时的布局管理器。

现在已经介绍完Android的5类布局管理器。这些布局各有特点,在开发时,应该根据实际应用的用户界面,选择合适的布局管理器。下面给出一些应用实例的用户界面,如图47所示。你能说出它们各使用了什么布局吗?

图47几种常见的用户界面布局

4.3Android常见的基本控件

部件(Widget)是为构建用户交互界面提供服务的视图对象。Android和其他开发语言一样,提供一套完整的部件实现。常用的Widget包括TextView、EditText、Button、RadioButton、Checkbox和ScrollView等。由于它们每一个都可以与用户进行交互,所以把Widget类中的每一个部件称为控件。

Widget类是View类的子类,Widget内的所有控件都继承了View类中的属性和方法。可以在android.widget包中找到Android提供的控件列表。下面分别进行介绍。

4.3.1TextView

TextView(文本框)是用来向用户显示文本内容的控件。它在android.widget.TextView包中定义,如果在Java类设计中使用它,则需要在相应的代码文件前部加上“import android.widget.TextView;”。

TextView控件中有很多可以在XML文件中设置的属性,这些属性同样可以在代码中以方法动态声明。常用的属性和对应的方法如表48所示。

表48TextView常用的属性和对应方法说明

属性方法描述

android:gravitysetGravity(int)设置TextView在x轴和y轴方向上的显示方式

android:heightsetHeight(int)设置TextView的高度,以像素为单位

android:widthsetWidth(int)设置TextView的宽度,以像素为单位

android:hintsetHint(int)当TextView中显示的文本内容为空时,显示的文本提示信息

android:paddingsetPadding(int)设置TextView中显示文本与其父容器边界的间距

android:textsetText(CharSequence)为TextView设置显示的文本内容

android:textColorsetTextColor(ColorStateList)设置TextView 的文本颜色

android:typefacesetTypeface(Typeface)设置TextView 的文本字体

android:textSizesetTextSize(float)设置TextView 的文本大小

android:textStylesetTextStyle(TextStyle)设置TextView 的文本字形,如粗体、斜体等

在使用中,要注意一些属性的区别。

1. android:gravity与android:layout_gravity的区别

android:gravity用于设置这个View内的所有子元素的对齐方式,而android:layout_gravity用于设置这个View在其父容器中的对齐方式。

2. android:padding与android:layout_margin的区别

padding是站在父View的角度描述问题的,它规定它里面的内容必须与这个父View边界的距离。而margin则是站在自己的角度描述问题的,规定自己和其他(上下左右)的View之间的距离,如果同一级只有一个View,那么它的效果基本上就和padding一样了。

图48一个TextView控件

【案例4.5】试设计如图48所示的布局文件片段。

【说明】这个TextView控件有背景色,需要使用android:background属性,文本颜色是白色的,需要使用android:textColor属性。颜色常量使用“#RRGGBB”6位十六进制数表示。

【代码】布局文件中的代码片断如下所示。

1TextView

2 android:id="@+id/text_view"

3 android:layout_width="fill_parent"

4 android:layout_height="wrap_content"

5 android:textSize="16sp"

6 android:textColor="#ffffff"

7 android:padding="10dip"

8 android:background="#cc0000"

9 android:text="这里是TextView,你可以在这里输入需要显示的文字信息.."

10/

(1) 第1~10行声明了一个TextView控件。

(2) 第5行设置文本的字符大小,即16sp。在2.2.1节中已经说明描述字符的单位使用sp。

(3) 第6行设置文本的颜色,“#ffffff”为纯白色。

(4) 第7行设置文本与其父容器(即文本框)边界的间距为10像素。可以看出图48中的文本与红色区域的边界是有10个像素的间隔。

(5) 第8行设置文本框的背景颜色,“#cc0000”为红色。

(6) 第9行设置文本框的显示内容。

4.3.2EditText

EditText(编辑框)是用来向用户显示文本内容,并允许用户对文本进行编辑的控件。在开发中经常会使用到这个控件,例如,实现登录界面时,需要用户输入账号、密码等信息,这时需要用到此编辑控件。EditText控件定义在android.widget.EditText包中,如果在Java类设计中使用它,则需要在相应的代码文件前部加上“import android.widget.EditText;”。

EditText类继承自TextView,有许多EditText控件中的属性和对应方法,对TextView控件同样适用。下面列出EditText控件常用的属性和方法,如表49所示。

表49EditText常用的属性和对应方法说明

属性方法描述

android:cursorVisiblesetCursorVisible (boolean)设置光标是否可见,默认可见

android:linessetLines(int)设置固定行数以确定EditText的高度

android:maxLinessetMaxLines(int)设置最大的行数

android:maxLengthsetFilters(InputFilter)设置最大的显示长度

android:passwordsetTransformationMethod(TransformationMethod)设置显示是否为密码模式

android:phoneNumbersetKeyListener(KeyListener)设置显示文本只能是电话号码

android:scrollHorizontallysetHorizontallyScrolling(boolean)设置文本框是否可以进行水平滚动

android:singleLinesetTransformationMethod(TransformationMethod)设置文本框为单行模式

图49一个EditText控件

【案例4.6】试设计如图49所示的布局文件片段。

【说明】这个EditText控件有一定的宽度,并且与屏幕右侧对齐,需要使用layout_gravity属性。注意,此时EditText控件中的文本是居中的,需要使用gravity属性。

【代码】布局文件中的代码片段如下所示。

1EditText android:id="@+id/edit_text"

2android:layout_width="100dip"

3android:layout_height="wrap_content"

4android:text="one"

5android:gravity="center"

6android:layout_gravity="right"/

(1) 第1~6行声明了一个EditText控件。

(2) 第2行设置EditText的宽度为100像素。

(3) 第5行设置EditText中的文本居中。

(4) 第6行设置EditText控件与屏幕右侧对齐。

4.3.3Button

Button(按钮)是用得最多的控件,在前面的多个示例中都已经见到了按钮。在Android平台中,按钮是通过Button来实现的。实现过程也非常简单。当用户对按钮按下或单击之后,按钮控件就会触发onClick事件,所以需要对按钮设置setOnClickListener事件监听。相关按钮的事件及事件监听将在第5章作详细介绍。

Button定义于android.widget.Button类中,如果在Java类设计中使用它,则需要在相应的代码文件前部加上“import android.widget. Button;”。

Button继承自TextView类,Button的背景可以是背景颜色,也可以是背景图片,Button上可显示文本,Button的大小可设置等,这些属性和相应的方法与TextView控件的属性和方法相同。

4.3.4ImageButton

ImageButton(图片按钮)控件与Button控件和功能一致,但在显示效果上是不一样的,它们的主要区别是ImageButton中没有text属性,即按钮中只显示图片而不显示文本。

ImageButton继承自ImageView类。ImageButton控件中设置按钮显示的图片可以通过android:src属性,如果在代码中动态设置图片则使用setImageResource(int)方法来实现。

在默认的情况下,ImageButton与Button一样都具有背景色,但是,为了不影响图片的显示,一般要将其背景色设置为透明或其他的图片。

下面通过一个案例来说明如何为ImageButton按钮的不同状态设置不同的显示图片。

【案例4.7】设计两个ImageButton按钮,这两个按钮在未被按下时都显示如图410(a)所示的图片。但当它们被按下时,第一个图

图410按钮图片

片按钮显示不同的背景色,而第二个图片按钮显示如图410(b)所示的图片。

【说明】首先必须把这两个图片文件存放在项目的res下的drawable目录中(也可以是drawablehdpi、drawableldpi或drawablemdpi),然后使用android:src属性为ImageButton设置显示图片。对于按钮一,只设置了按钮未被按下时显示的图片,对于按钮二,还需要设置按钮被按下时显示的图片,这时,需要在图片资源存放的目录中编写一个XML文件,用于描述按钮的两个状态各显示的图片。

【布局设计步骤】

(1) 这里,如图410(a)所示的图片文件名为play.png,如图410(b)所示的图片文件名为playb.png。在该项目的res目录中创

建一个名为drawable的目录,将这两个图片文件复制到新建的目录中。

(2) 在res/layout目录下创建一个名为myselector.xml的文件,用于设置按钮在不同状态下显示不同的图片文件,代码如下所示。

1?xml version="1.0" encoding="utf-8"?

2selector xmlns:android="http://schemas.android.com/apk/res/android"

3item

4android:state_pressed="false"

5android:drawable="@drawable/play"/!-- 设置按钮未被按下时的图片 --

6item

7android:state_pressed="true"

8android:drawable="@drawable/playb"/!-- 设置按钮按下时的图片 --

9/selector

① 第2~19行声明图片按钮的选择标签,使用<selector>标签。

② 第3~5行声明按钮未被按下状态时的图片资源。这里使用<item>标签,按钮未被按下时用“android:state_pressed="false"”判断,用属性设置图片源,即“android:drawable="@drawable/play"”。

③ 第6~8行声明按钮被按下状态时的图片资源,此时设置图片资源为“android:drawable="@drawable/playb"”。

(3) 编写res/layout目录下的布局文件,在这个项目中设计本案例的布局文件名为image_button.xml文件,代码如下所示。

1?xml version="1.0" encoding="utf-8"?

2LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

3android:orientation="vertical" android:layout_width="fill_parent"

4android:layout_height="wrap_content"

5

6TextView

7android:layout_width="wrap_content"

8android:layout_height="wrap_content"

9android:text="两个图片按钮:" /

10

11ImageButton

12android:id="@+id/image_button1"

13android:src="@drawable/play"

14android:layout_width="wrap_content"

15android:layout_height="wrap_content"/

16ImageButton

17android:id="@+id/image_button2"

18android:src="@drawable/myselector"

19android:layout_width="wrap_content"

20android:layout_height="wrap_content"/

21

22/LinearLayout

① 第2~22行声明了一个线性布局。其内有三个控件,一个TextView控件,两个ImageButton控件。

图411两按钮都未被按下时

的显示效果

② 第11~15行声明第一个图片按钮,其ID为“image_button1”。第13行设置该按钮未被按下时的显示图片为图片资源目录中的“play.png”。

③ 第16~20行声明第二个图片按钮,其ID为“image_button2”。第18行设置该按钮未被按下和被按下两种状态的显示图片由图片资源目录中的myselector.xml文件描述。

【运行效果】图411~图413分别是这两个图片按钮在两种状态下的运行效果。

图412当按钮一被按下时的显示效果

图413当按钮二被按下时的显示效果

4.3.5Checkbox和RadioButton

CheckBox与RadioButton(复选按钮与单选按钮)是开发中经常需要用到的选择按钮,通常一组单选按钮需要编制到一个RadioGroup中。相信读者对它们并不陌生。CheckBox与RadioButton都继承自CompoundButton类,它们也都从父类CompoundButton中继承了一些成员方法,常用的方法及说明如表410所示。

表410CheckBox与RadioButton常用的方法及说明

方法描述

isChecked ()判断是否被选中,如果被选中返回true,否则返回false

performClick()调用OnClickListener监听器,即模拟一次单击

setChecked(boolean checked)通过传入的参数设置控件状态

toggle()置反控件当前的状态,即原为选中状态时返回未选中状态,或原为未选中状态时返回选中状态

setOnCheckedChangeListener

(CompoundButton.OnCheckedChangeListener listener)为控件设置OnCheckedChangeListener监听器

【案例4.8】试设计如图414所示的布局文件片段。

【说明】这组CheckBox控件是将文本标签的字形作为复选项,并且是以所见即所得的形式,标注什么字形就显示什么字形,因此用textStyle属性。

【代码】布局文件中的代码片段如下所示。

1CheckBox android:id="@+id/plain_cb"

2android:text="Plain"

3android:layout_width="wrap_content"

4android:layout_height="wrap_content"

5/

6CheckBox android:id="@+id/serif_cb"

7android:text="Serif"

8android:layout_width="wrap_content"

9android:layout_height="wrap_content"

10android:typeface="serif"

11/

12CheckBox android:id="@+id/bold_cb"

13android:text="Bold"

14android:layout_width="wrap_content"

15android:layout_height="wrap_content"

16android:textStyle="bold"

17/

18CheckBox android:id ="@+id/italic_cb"

19android:text="Italic"

20android:layout_width="wrap_content"

21android:layout_height="wrap_content"

22android:textStyle="italic"

23/

(1) 这里声明了4个CheckBox控件。

(2) 第10、16、22行设置CheckBox控件显示标签的字形。

图414一组CheckBox控件

图415一组RadioButton控件

【案例4.9】试设计如图415所示的布局文件片段。

【说明】这组RadioButton控件是将一日的餐名列出,供选择。如果有多个单选按钮组成一组,需要用一个RadioGroup控件把它们编成一组,在这个组内,同一时刻只能有一个按钮处于选中状态。

【代码】布局文件中的代码片段如下所示。

1RadioGroup

2 android:layout_width="fill_parent"

3 android:layout_height="wrap_content"

4 android:orientation="vertical"

5 android:checkedButton="@+id/lunch"

6 android:id="@+id/menu"

7 RadioButton

8 android:text="breakfast"

9 android:id="@+id/breakfast" /

10RadioButton

11android:text="lunch"

12android:id="@id/lunch" /

13RadioButton

14android:text="dinner"

15android:id="@+id/dinner" /

16RadioButton

17android:text="all"

18android:id="@+id/all" /

19/RadioGroup

(1) 第1~19行声明了一个RadioGroup控件,其内定义了4个RadioButton按钮。

(2) 第4行设置这组单选按钮是纵向排列的。

(3) 第5行设置这个RadioGroup组中ID为“lunch”的单选按钮为选中状态。

4.3.6ImageView

1. ImageView(图片)控件

ImageView控件负责显示图片。除了显示图片之外,还可以对图片执行一些其他的操作,例如设置它的alpha值,调整图片的尺寸等。

图片来源有多种途径: 可以是资源文件的ID,也可以是drawable目录中的图片对象,还可以是Content Provider中的URI等。ImageView控件中常用到的属性和对应方法如表411所示。

表411ImageView中常用的属性和对应方法说明

属性方法描述

android:adjustViewBoundssetAdjustViewBounds(boolean)设置是否需要ImageView调整自己的边界来保证显示的图片的长宽比例

android:maxHeightsetMaxHeight(int)可选项,设置ImageView的最大高度

android: maxWidthsetMaxWidth(int)可选项,设置ImageView的最大宽度

android:scaleTypesetScaleType(ImageView.ScaleType)调整或移动图片来适应ImageView的尺寸。如: 当ScaleType取值为center/CENTER时按图片的原尺寸居中显示; 当ScaleType取值为centerCrop/CENTER_CROP时按比例扩大图片尺寸并居中显示; 当ScaleType取值为fitCenter /FIT_CENTER时把图片按比例扩大/缩小到View的宽度,居中显示; 当ScaleType取值为fitXY/FIT_XY时把图片不按比例扩大/缩小到View的大小显示

android:srcsetImageResource(int)设置ImageView要显示的图片源

ImageView控件还有些常用成员方法,如表412所示。

表412ImageView中常用的方法说明

方法描述

setAlpha(int) 设置ImageView的透明度

setImageBitmap(Bitmap) 设置ImageView所显示的内容为指定的Bitmap对象

setImageDrawable (Drawable)设置ImageView所显示的内容为指定的Drawable对象

setImageResource (int)设置ImageView所显示的内容为指定ID的资源

setImageURI(Uri)设置ImageView所显示的内容为指定URI

setSelected(boolean)设置ImageView的选中状态

图416一个ImageView控件

【案例4.10】试设计如图416所示的布局文件片段。

【说明】这个界面中除了显示了一个水平居中的ImageView控件外,在其上方还有一串文本。本界面实际上有两个控件。

【代码】布局文件中的代码片段如下所示。

1TextView

2android:layout_width="wrap_content"

3android:layout_height="wrap_content"

4android:text="安卓图片是这样的:" /

5

6ImageView

7android:id="@+id/imagebutton"

8android:src="@drawable/andd"

9android:layout_width="wrap_content"

10android:layout_height="wrap_content"

11android:layout_gravity="center"

12/

(1) 第1~4行声明了一个TextView控件,显示文本信息。

(2) 第6~12行声明了一个ImageView控件。其中,第8行设置该控件的图片来源于drawable目录中的andd.png文件; 第11行设置该图片控件位于屏幕的横向居中位置。

Android支持常见的静态图片格式,如: PNG、9.PNG、JPG和GIF格式等。 注意,Android还不支持动态的GIF格式。这里提到的9.PNG格式的图是一种比较特别的图片格式,下面专门介绍。

2. 9Patch图片简介

9Patch图片是一种特殊的PNG图片格式,以“.9.png”结尾。9Patch图片可以实现部分拉伸,这种图片与通常的只以“.png”结尾的图片不一样,如果直接拉伸普通的PNG图会有失真现象出现,所以它通常被用作背景图使用。

9Patch图片和普通图片的区别是四周多了一个边框,如图417所示。

1) 9Patch图片的伸缩规则

9Patch图片的伸缩规则主要由左、上侧,右、下侧的黑线确定。一般情况左侧黑线比右侧的短,上侧黑线比下侧的短。右侧和下侧的黑线可以省略。

如图418所示,以左侧和上侧的黑线两端为标准,可画出4条直线,将原图切割成9个区域(4个角,4条边缘和一个中心区域),各个区域有不同的拉伸控制(角落不拉伸,横边横向拉伸,竖边竖向拉伸,中心区域横竖向都拉伸)。这样,使用 9patch图片在伸缩时,其圆角及边缘可避免变形。

如图419所示,右边的黑色线代表内容绘制的垂直区域,下边的黑色线代表内容绘制的水平区域,以右侧和下侧的黑线两端为标准,可画出4条直线。9Patch图片能显示内容的区域就是这4条直线所围的中间区域,其中包含经过伸缩的变形区域。

图417一个作为按钮背景的9Patch图片

图418确定伸缩区域

图419确定显示内容区域

2) 9Patch图片与一般PNG图片的比较

通过下面的一组对照图示,如图420与图421所示,可以清楚地比较出图.9.png与图.png的区别。

图4209Patch图片经过拉伸后与原始

图片的比较

图421一般的png图片经过拉伸后与原始

图片的比较

Android提供了一个制作9Patch图片的工具,即在SDK的安装文件夹的tools文件夹下,可以找到draw9patch.bat文件。运行该文件即可打开一个9Patch图制作工具,利用它可以将一个普通的图片加工成一个9Patch图片。

4.3.7AnalogClock和DigitalClock

在Android中显示时钟信息的有AnalogClock 和DigitalClock两个控件。不同的是,AnalogClock以模拟时钟指针的形式显示时间,且只有时针和分针,而DigitalClock以数字形式显示时间,可以精确到秒。它们都位于android.widget包下。

【案例4.11】试设计如图422所示的布局文件片段。

图422时钟显示效果

【说明】这个界面使用了两种控件来显示时间信息,一种是模拟时钟的,一种是以数字形式的,它们都水平居中于屏幕。

【代码】布局文件中的代码片段如下所示。

1AnalogClock

2android:id="@+id/analog"

3android:layout_width="wrap_content"

4android:layout_height="wrap_content"

5android:layout_gravity="center_horizontal"

6/!-- 声明一个AnalogClock控件 --

7DigitalClock

8android:id="@+id/digital"

9android:layout_width="wrap_content"

10android:layout_height="wrap_content"

11android:layout_gravity="center_horizontal"

12/!-- 声明一个DigitalClock控件 --

(1) 第1~6行声明了一个AnalogClock控件,并水平居中。

(2) 第7~12行声明了一个DigitalClock控件,并水平居中。

4.3.8DatePicker和TimePicker

日期和时间是任何手机都会有的基本功能。Android也不例外。Android平台用DatePicker控件来显示日期,用TimePicker控件来显示时间,并且显示的界面非常精致漂亮。

1. 日期控件

DatePicker用于向用户提供包含年、月、日的日期数据,并允许用户对其进行修改。如果用户对日期进行了修改,需要使用onDateChangedListener监听器来捕获用户修改的日期数据。DatePicker继承自FrameLayout类。其主要的成员方法如表413所示。

表413DatePicker类的主要方法及说明

方法描述

getDayOfMonth() 获取日期天数

getMonth()获取日期月份

getYear ()获取日期年份

init (int year,int monthOfYear,int dayOfMonth,

DatePicker.OnDateChangedListener onDateChangedListener)初始化DatePicker的属性,以onDateChangedListener 为监听器对象,负责监听日期数据的变化

setEnabled(boolean enabled)根据传入的参数设置DatePicker控件是否可用

updateDate(int year,int monthOfYear,int dayOfMonth)根据传入的参数更新DatePicker控件的各个属性值

【案例4.12】试设计如图423所示的布局文件片段。

图423日期选择控件的显示效果

【说明】这就是Android的DatePicker控件,使用它既可以显示日期,也可以修改日期。因为它继承自FrameLayout类,所以它是以屏幕的左上角对齐方式显示的。

【代码】布局文件中的代码片段如下所示。

1DatePicker

2android:id="@+id/date_picker"

3android:layout_width="wrap_content"

4android:layout_height="wrap_content" /

2. 时间控件

TimePicker用于向用户提供一天中的时间,可以是24小时制,也可以为AM/PM制,并允许用户对其进行修改。如果要捕获用户修改时间事件,需要添加onTimeChangedListener监听器对TimePicker进行监听。TimePicker同样继承自FrameLayout类。其常用的成员方法如表414所示。

表414TimePicker类的常用方法及说明

方法描述

getCurrentHour () 获取TimePicker控件的当前小时,返回Integer对象

getCurrentMinute ()获取TimePicker控件的当前分钟,返回Integer对象

is24HourView ()判断TimePicker控件是否为24小时制

setCurrentHour (int currentHour)设置TimePicker控件的当前小时,传入Integer对象

setCurrentMinute(int currentMinute)设置TimePicker控件的当前分钟,传入Integer对象

setEnabled(boolean enabled)根据传入的参数设置TimePicker控件是否可用

setIs24HourView(boolean is24HourView)根据传入的参数设置TimePicker是否为24小时制

setOnTimeChangedListener(TimePicker.OnTimeChangedListener onTimeChangedListener)为TimePicker添加OnTimeChangedListener监听器

图424时间选择控件的显示效果

【案例4.13】试设计如图424所示的布局文件片段。

【代码】布局文件中的代码片段如下所示。

1TimePicker

2android:id="@+id/time_picker"

3android:layout_width="wrap_content"

4android:layout_height="wrap_content" /

4.4简单的UI设计案例

下面通过一个应用项目的用户界面设计过程来理解本章前三节所介绍的主要内容。

【案例4.14】设计一个“掌上微博”的用户登录界面。要求界面友好,使用方便。

【说明】通常一个用户登录界面需要有这样三个方面的要素: 应用项目的名称,用户的账号与密码输入,“登录”和“注册”按钮。

应用项目的名称一般可使用TextView控件显示。

用户的账号与密码输入需要用TextView控件为输入区作提示,还需要使用编辑控件EditText,让用户可以进行相关信息输入,还要注意,在输入密码时要将输入的信息隐藏。

图425用户登录界面规划

“登录”和“注册”按钮使用Button控件就可以了。

为了界面更好看一些,最好配一个背景图作装饰。

为了统一界面的文字表述,需要编写字符串资源文件strings.xml。

为了统一界面风格,各部分文本的字体、字大小、字颜色、边框等,需要编写样式文件styles.xml。

【布局设计过程】

(1) 绘出“掌上微博”的用户登录界面草图。在本书中使用的Android模拟器屏幕的分辨率是320×480像素,按此比例画出一个登录界面的草图如图425所示。其中矩形表示线性布局LinearLayout,圆角矩形表示控件。

(2) 从草图中得出以下设计方案。

① 一个外层LinearLayout。

设置LinearLayout背景图。

为纵向排列布局。

一个TextView控件显示应用标题,三个LinearLayout嵌套。

② 应用标题TextView控件。

设置宽度为full_parent,高度为文本高度。

设置水平居中对齐方式。

设计字体颜色与字体大小,注意与背景图的色彩搭配与大小适中。

③ 账号信息LinearLayout。

为横向排列布局。

与上一个对象要有一定间距。

一个TextView控件显示“账号: ”,左对齐屏幕,并且设置适当的宽度值。

一个EditText控件用于输入账号,并且设置适当的宽度值。

④ 密码信息LinearLayout。

与账号信息LinearLayout及其内部的控件属性设置基本相同。

用于密码输入的EditText控件,要设置android.password为true。

⑤ 按钮LinearLayout。

为横向排列布局。

与父布局保持一定间距。

两个按钮为右对齐方式。

设置适当的按钮宽度值。

(3) 在Eclipse中创建一个名为ZSWB_Login1的Android项目。其应用程序名为ZSWB,包名为cn.com.sgmsc.ZSWB,Activity组件名为Login1Activity。

(4) 将图片资源复制到本项目的res/drawablemdpi目录中。

(5) 编写res/values目录下的strings.xml文件,代码如下所示。

1?xml version="1.0" encoding="utf-8"?

2resources

3string name="hello"Hello World, ZSWB!/string

4string name="app_name"掌上微博/string

5string name="ZSWB"掌上微博/string

6string name="tvUid"账 号: /string

7string name="tvPwd"密 码: /string

8string name="btnLogin"登录/string

9string name="btnReg"注册/string

10/resources

(6) 在res/values目录下创建名为styles.xml样式文件,并编辑之。代码如下所示。

1?xml version="1.0" encoding="utf-8"?

2resources

3style name="title"

4item name="android:textSize"32sp/item

5item name="android:textColor"#f37301/item

6item name="android:textStyle"bold/item

7/style

8style name="text"

9item name="android:textSize"18sp/item

10item name="android:textColor"#f37301/item

11item name="android:textStyle"bold/item

12/style

13style name="button"

14item name="android:textSize"20sp/item

15item name="android:textColor"#f37301/item

16item name="android:textStyle"bold/item

17/style

18/resources

(7) 重命名res/layout目录下的main.xml文件为long.xml,并编辑之。代码如下所示。

1?xml version="1.0" encoding="utf-8"?

2LinearLayout

3xmlns:android="http://schemas.android.com/apk/res/android"

4android:orientation="vertical"

5android:layout_width="fill_parent"

6android:layout_height="fill_parent"

7android:gravity="center_horizontal"

8android:background="@drawable/back"

9!-- 声明垂直分布的线性布局 --

10

11TextView

12android:id="@+id/TextView0"

13android:text="@string/ZSWB"

14style="@style/title"

15android:paddingTop="20dip"

16android:paddingBottom="20dip"

17android:layout_width="fill_parent"

18android:layout_height="wrap_content"

19android:gravity="center"

20android:password="false"

21

22/TextView

23

24LinearLayout

25  android:orientation="horizontal"

26android:paddingTop="25px"

27android:layout_width="wrap_content"

28android:layout_height="wrap_content"

29android:layout_gravity="center_horizontal"

30

31TextView

32android:text="@string/tvUid"

33android:layout_width="100px"

34style="@style/text"

35android:layout_height="wrap_content"

36android:layout_gravity="center_vertical"

37/

38EditText

39android:id="@+id/etUid"

40android:singleLine="true"

41android:layout_width="150px"

42android:layout_height="wrap_content"

43/

44 /LinearLayout

45

46LinearLayout

47android:orientation="horizontal"

48android:layout_width="wrap_content"

49android:layout_height="wrap_content"

50android:layout_gravity="center_horizontal"

51

52TextView

53android:text="@string/tvPwd"

54style="@style/text"

55android:layout_width="100px"

56android:layout_height="wrap_content"

57android:layout_gravity="center_vertical"

58/

59EditText

60android:id="@+id/etPwd"

61android:singleLine="true"

62android:password="true"

63android:layout_width="150px"

64android:layout_height="wrap_content"

65/

66 /LinearLayout

67

68LinearLayout

69android:paddingTop="20dip"

70android:paddingBottom="20dip"

71android:paddingRight="20dip"

72android:orientation="horizontal"

73android:gravity="right"

74android:layout_width="fill_parent"

75android:layout_height="wrap_content"

76 !-- 声明于显示按钮的线性布局 --

77Button

78android:id="@+id/btnLogin"

79android:text="@string/btnLogin"

80style="@style/button"

81android:minWidth="70dip"

82android:layout_width="wrap_content"

83android:layout_height="wrap_content"

84/

85Button

86android:id="@+id/btnReg"

87android:text="@string/btnReg"

88style="@style/button"

89android:minWidth="70dip"

90android:layout_width="wrap_content"

91android:layout_height="wrap_content"

92/

93/LinearLayout

94

95/LinearLayout

① 第2~9行声明一个外层的LinearLayout布局。其中第8行设置了一个背景图,该背景图片取自于res/drawablemdpi目录中的back.jpg文件。

② 第11~22行声明一个TextView控件用于显示应用标题。其中,第13行为控件设置显示的内容,其内容取自字符串资源文件strings.xml中名为“ZSWB”的内容; 第14行设置控件文本显示风格,其文本风格由样式文件styles.xml中名为“title”的样式所定义; 第15行和第16行设置该控件与其相邻的上、下控件的间距为20像素。

③ 第24~44行声明了一个内嵌的LinearLayout布局。其中,第31~37行声明了一个TextView控件,其显示的文本取自于字符串资源文件strings.xml中名为“tvUid”的内容,文本显示风格由样式文件styles.xml中名为“text”的样式所定义; 第38~43行声明了一个EditText控件,第40行设置该EditText为单行的编辑框。

图426“掌上微博”用户登录界面

④ 第46~66行声明了第二个内嵌的LinearLayout布局。其中,第59~65行声明了一个输入密码的EditText控件,第62行设置该EditText为password为true的编辑框。

⑤ 第68~93行声明了第三个内嵌的LinearLayout布局。其中,声明了两个Button控件,第81行、第89行分别设置这两个Button的最小宽度为70像素,以确保按钮上的文本能显示完整。

由于本例只是在为“掌上微博”的用户登录界面作设计,并没有做任何实质性的代码编写工作,所以就不用编写项目的代码文件和AndroidManifest.xml文件了。

【运行结果】在Eclipse中启动Android模拟器,然后运行ZSWB_Login1项目。运行结果如图426所示。

小结

本章简单介绍了Android应用程序用户界面的所有控件的基类View和所有容器类的基类ViewGroup。详细介绍了Android的5种布局类,以及11个Android的基本控件类。分别通过布局描述文件对这些常用的布局类和基本控件类的属性及其方法进行举例说明。最后通过一个实用程序的用户登录界面设计过程,为读者演示一个应用的用户界面是怎样创建出来的。

是否熟练地掌握了这些布局和基本控件的XML描述方法就能够开发出各种各样的用户界面了呢?回答是: 否。还有一些屏幕元素如各类视图、选项卡、进度条等控件。是否所有的用户界面都只需要在其布局文件中进行描述,而不需要在代码文件中进行定义呢?答案也是: 否。有些控件还必须结合相关的代码才能定义完全。这些知识将在第5章中介绍,请继续学习。

练习

1. 设计一个自己微博的登录界面,要求有“账号”和“密码”两个输入编辑框,有“登录”和“注册”两个按钮。

2. 设计一个自己微博的注册界面,要求至少有“账号昵称”、“密码”、“确认密码”等输入编辑框,有“注册”和“返回”两个按钮。