第3章 用户界面设计
(教学录像:4小时57分钟)
通过前面的学习,相信读者已经对Android有了一定的了解,本章将学习Android开发中一项很重要的内容——用户界面设计。Android提供了多种控制UI界面的方法、布局方式,以及大量功能丰富的UI组件,通过这些组件,可以像搭积木一样,开发出优秀的用户界面。
通过阅读本章,您可以:
★ 掌握控制UI界面的4种方法
★ 掌握线性布局、表格布局、帧布局和相对布局管理器的应用
★ 掌握文本框和编辑框的基本应用
★ 掌握单选按钮、单选按钮组和复选按钮的基本应用
★ 掌握普通按钮和图片按钮的使用方法
★ 掌握图像视图和列表视图的应用
★ 掌握列表选择框的使用方法
★ 掌握日期、时间选择器及计时器的基本应用
3.1 控制UI界面
教学录像:光盘\TM\lx\3\控制UI界面.exe
用户界面设计是Android应用开发的一项重要内容。在进行用户界面设计时,首先需要了解页面中的UI元素如何呈现给用户,也就是如何控制UI界面。Android提供了4种控制UI界面的方法,下面分别进行介绍。
3.1.1 使用XML布局文件控制UI界面
Android提供了一种非常简单、方便的方法用于控制UI界面。该方法采用XML文件来进行界面布局,从而将布局界面的代码和逻辑控制的Java代码分离开来,使程序的结构更加清晰、明了。
使用XML布局文件控制UI界面可以分为以下两个关键步骤。
(1)在Android应用的res\layout目录下编写XML布局文件,可以采用任何符合Java命名规则的文件名。创建后,R.java会自动收录该布局资源。
(2)在Activity中使用以下Java代码显示XML文件中布局的内容。
- setContentView(R.layout.main);
在上面的代码中,main是XML布局文件的文件名。
通过上面的步骤就可轻松实现布局并显示UI界面的功能。下面通过一个具体的例子来演示如何使用XML布局文件控制UI界面。
例3.1 在Eclipse中创建Android项目,名称为3.1,使用XML布局文件实现游戏的开始界面。(实例位置:光盘\TM\sl\3\3.1)
(1)修改新建项目3.1的res\layout目录下的布局文件main.xml。在该文件中,采用帧布局(FrameLayout),并且添加两个TextView组件,第1个用于显示提示文字,第2个用于在窗体的正中间位置显示开始游戏按钮。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/background"
- >
- <!-- 添加提示文字 -->
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/title"
- style="@style/text"
- />
- <!-- 添加开始按钮 -->
- <TextView
- android:id="@+id/startButton"
- android:layout_gravity="center_vertical|center_horizontal"
- android:text="@string/start"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- style="@style/text"
- />
- </FrameLayout>
说明:在布局文件main.xml中,通过设置布局管理器的android:background属性,可以为窗体设置背景图片;通过设置具体组件的style属性,可以为组件设置样式;使用android:layout_gravity= "center_vertical|center_horizontal",可以让该组件在帧布局中居中显示。
(2)修改res\values目录下的strings.xml文件,并且在该文件中添加一个用于定义开始按钮内容的常量,名称为start,内容为“单击开始游戏……”。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="title">使用XML布局文件控制UI界面</string>
- <string name="app_name">3.1</string>
- <string name="start">单击开始游戏......</string>
- </resources>
说明:strings.xml文件用于定义程序中应用的字符串常量。其中,每一个<string>子元素都可以定义一个字符串常量,常量名称由name属性指定,常量内容写在起始标记<string>和结束标记</string>之间。
(3)为了改变窗体中文字的大小,需要为TextView组件添加style属性,用于指定应用的样式。具体的样式需要在res\values目录中创建的样式文件中指定。在本实例中,创建一个名称为styles.xml的样式文件,并在该文件中创建一个名称为text的样式,用于指定文字的大小和颜色。sytles.xml文件的具体代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <style name="text">
- <item name="android:textSize">24px</item>
- <item name="android:textColor">#111111</item>
- </style>
- </resources>
(4)在主活动,也就是MainActivity中,应用以下代码指定活动应用的布局文件。
- setContentView(R.layout.main);
说明:在应用Eclipse创建Android项目时,Eclipse会自动在主活动的onCreate()方法中添加指定布局文件main.xml的代码。
在模拟器上运行本实例,将显示如图3.1所示的运行结果。
图3.1 实现游戏的开始界面
3.1.2 在代码中控制UI界面
Android支持像Java Swing那样完全通过代码控制UI界面。也就是所有的UI组件都通过new关键字创建出来,然后将这些UI组件添加到布局管理器中,从而实现用户界面。
在代码中控制UI界面可以分为以下3个关键步骤。
(1)创建布局管理器,可以是帧布局管理器、表格布局管理器、线性布局管理器和相对布局管理器等,并且设置布局管理器的属性。例如,为布局管理器设置背景图片等。
(2)创建具体的组件,可以是TextView、ImageView、EditText和Button等任何Android提供的组件,并且设置组件的布局和各种属性。
(3)将创建的具体组件添加到布局管理器中。
下面通过一个具体的实例来演示如何使用Java代码控制UI界面。
例3.2 在Eclipse中创建Android项目,名称为3.2,完全通过代码实现游戏的进入界面。(实例位置:光盘\TM\sl\3\3.2)
(1)在新创建的项目中,打开src\com\mingrisoft目录下的MainActivity.java文件,然后将默认生成的下面这行代码删除。
- setContentView(R.layout.main);
(2)在MainActivity的onCreate()方法中,创建一个帧布局管理器,并为该布局管理器设置背景,关键代码如下:
- FrameLayout frameLayout = new FrameLayout(this); //创建帧布局管理器
- frameLayout.setBackgroundDrawable(this.getResources().getDrawable(
- R.drawable.background)); //设置背景
- setContentView(frameLayout); //设置在Activity中显示frameLayout
(3)创建一个TextView组件text1,设置其文字大小和颜色,并将其添加到布局管理器中,具体代码如下:
- TextView text1 = new TextView(this);
- text1.setText("在代码中控制UI界面"); //设置显示的文字
- text1.setTextSize(TypedValue.COMPLEX_UNIT_PX, 24); //设置文字大小,单位为像素
- text1.setTextColor(Color.rgb(1, 1, 1)); //设置文字的颜色
- frameLayout.addView(text1); //将text1添加到布局管理器中
(4)声明一个TextView组件text2,因为在为该组件添加的事件监听中,要通过代码改变该组件的值,所以需要将其设置为MainActivity的一个属性,关键代码如下:
- public TextView text2;
(5)实例化text2组件,设置其显示文字、文字大小、颜色和布局,具体代码如下:
- text2 = new TextView(this);
- text2.setText("单击进入游戏......"); //设置显示文字
- text2.setTextSize(TypedValue.COMPLEX_UNIT_PX, 24); //设置文字大小,单位为像素
- text2.setTextColor(Color.rgb(1, 1, 1)); //设置文字的颜色
- LayoutParams params = new LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT); //创建保存布局参数的对象
- params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL; //设置居中显示
- text2.setLayoutParams(params); //设置布局参数
说明:在通过setTextSize()方法设置TextView的文字大小时,可以指定使用的单位。在上面的代码中,int型的常量TypedValue.COMPLEX_UNIT_PX表示单位是像素,如果要设置单位为磅,可以使用常量TypedValue.COMPLEX_UNIT_PT,这些常量可以在Android官方提供的API中找到。
(6)为text2组件添加单击事件监听器,并将该组件添加到布局管理器中,具体代码如下:
- text2.setOnClickListener(new OnClickListener() { //为text2添加单击事件监听器
- @Override
- public void onClick(View v) {
- new AlertDialog.Builder(MainActivity.this).setTitle("系统提示") //设置对话框的标题
- .setMessage("游戏有风险,进入需谨慎,真的要进入吗?") //设置对话框的显示内容
- .setPositiveButton("确定", //为“确定”按钮添加单击事件
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Log.i("3.2", "进入游戏"); //输出消息日志
- }
- }).setNegativeButton("退出", //为“退出”按钮添加单击事件
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Log.i("3.2", "退出游戏"); //输出消息日志
- finish(); //结束游戏
- }
- }).show(); //显示对话框
- }
- });
- frameLayout.addView(text2); //将text2添加到布局管理器中
运行本实例,将显示如图3.2所示的运行结果。
图3.2 通过代码布局游戏开始界面
单击文字“单击进入游戏……”,将弹出如图3.3所示的提示对话框。
图3.3 系统提示对话框
说明:完全通过代码控制UI界面虽然比较灵活,但是其开发过程比较烦琐,而且不利于高层次的解耦,因此不推荐采用这种方式控制UI界面。
3.1.3 使用XML和Java代码混合控制UI界面
完全通过XML布局文件控制UI界面,实现比较方便快捷,但是有失灵活;而完全通过Java代码控制UI界面,虽然比较灵活,但是开发过程比较烦琐。鉴于这两种方法的优缺点,下面来看另一种控制UI界面的方法,即使用XML和Java代码混合控制UI界面。
使用XML和Java代码混合控制UI界面,习惯上把变化小、行为比较固定的组件放在XML布局文件中,把变化较多、行为控制比较复杂的组件交给Java代码来管理。下面通过一个具体的实例来演示如何使用XML和Java代码混合控制UI界面。
例3.3 在Eclipse中创建Android项目,名称为3.3,通过XML和Java代码在窗体中横向并列显示4张图片。(实例位置:光盘\TM\sl\3\3.3)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认创建的<TextView>组件删除,然后将默认创建的线性布局的orientation属性值设置为horizontal(水平),并且为该线性布局设置背景以及id属性。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/background"
- android:id="@+id/layout"
- >
- </LinearLayout>
(2)在MainActivity中,声明img和imagePath两个成员变量,其中,img是一个ImageView类型的一维数组,用于保存ImageView组件;imagePath是一个int型的一维数组,用于保存要访问的图片资源。关键代码如下:
- private ImageView[] img=new ImageView[4]; //声明一个保存ImageView组件的数组
- private int[] imagePath=new int[]{
- R.drawable.img01,R.drawable.img02,R.drawable.img03,R.drawable.img04
- }; //声明并初始化一个保存访问图片的数组
(3)在MainActivity的onCreate()方法中,首先获取在XML布局文件中创建的线性布局管理器,然后通过一个for循环创建4个显示图片的ImageView组件,并将其添加到布局管理器中。关键代码如下:
- setContentView(R.layout.main);
- LinearLayout layout=(LinearLayout)findViewById(R.id.layout); //获取XML文件中定义的线性布局管理器
- for(int i=0;i<imagePath.length;i++){
- img[i]=new ImageView(this); //创建一个ImageView组件
- img[i].setImageResource(imagePath[i]); //为ImageView组件指定要显示的图片
- img[i].setPadding(5, 5, 5, 5); //设置ImageView组件的内边距
- LayoutParams params=new LayoutParams(253,148); //设置图片的宽度和高度
- img[i].setLayoutParams(params); //为ImageView组件设置布局参数
- layout.addView(img[i]); //将ImageView组件添加到布局管理器中
- }
运行本实例,将显示如图3.4所示的运行结果。
图3.4 在窗体中横向并列显示4张图片
3.1.4 开发自定义的View
在Android中,所有的UI界面都是由View类和ViewGroup类及其子类组合而成的。其中,View类是所有UI组件的基类,而ViewGroup类是容纳这些UI组件的容器,其本身也是View类的子类。在ViewGroup类中,除了可以包含普通的View类外,还可以再次包含ViewGroup类。View类和ViewGroup类的层次结构如图3.5所示。
图3.5 Android UI组件的层次结构
一般情况下,开发Android应用程序的UI界面,都不直接使用View和ViewGroup类,而是使用这两个类的子类。例如,要显示一张图片,就可以使用View类的子类ImageView。虽然Android提供了很多继承了View类的UI组件,但是在实际开发时,还会出现不足以满足程序需要的情况。这时,用户就可以通过继承View类来开发自已的组件。开发自定义的View组件大致分为以下3个步骤。
(1)创建一个继承android.view.View类的View类,并且重写构造方法。
(2)根据需要重写相应的方法。可以通过下面的方法找到可以被重写的方法。
在代码中单击鼠标右键,在弹出的快捷菜单中选择“源代码”/“覆盖/实现方法”命令,将打开如图3.6所示的窗口,在该窗口的列表框中显示出了可以被重写的方法。只需要选中要重写方法前面的复选框,并单击“确定”按钮,Eclipse将自动重写指定的方法。通常情况下,不需要重写全部方法。
图3.6 “覆盖/实现方法”窗口
(3)在项目的活动中,创建并实例化自定义View类,并将其添加到布局管理器中。
下面通过一个具体的实例来演示如何开发自定义的View类。
例3.4 在Eclipse中创建Android项目,名称为3.4,自定义View组件实现跟随手指的小兔子。(实例位置:光盘\TM\sl\3\3.4)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认创建的<LinearLayout>和<TextView>组件删除,然后添加一个帧布局管理器FrameLayout,并且设置其背景和id属性。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/background"
- android:id="@+id/mylayout"
- >
- </FrameLayout>
(2)创建一个名称为RabbitView的Java类,该类继承自android.view.View类,重写带一个参数Context的构造方法和onDraw()方法。其中,在构造方法中设置兔子的默认显示位置,在onDraw()方法中根据图片绘制小兔子。RabbitView类的关键代码如下:
- public class RabbitView extends View {
- public float bitmapX; //小兔子显示位置的X坐标
- public float bitmapY; //小兔子显示位置的Y坐标
- public RabbitView(Context context) { //重写构造方法
- super(context);
- bitmapX = 750; //设置小兔子默认显示位置的X坐标
- bitmapY = 500; //设置小兔子默认显示位置的Y坐标
- }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Paint paint = new Paint(); //创建并实例化Paint的对象
- Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),
- R.drawable.rabbit); //根据图片生成位图对象
- canvas.drawBitmap(bitmap, bitmapX, bitmapY, paint); //绘制小兔子
- if (bitmap.isRecycled()) { //判断图片是否回收
- bitmap.recycle(); //强制回收图片
- }
- }
- }
(3)在主活动的onCreate()方法中,首先获取帧布局管理器并实例化小兔子对象rabbit,然后为rabbit添加触摸事件监听器,在重写的触摸事件中设置rabbit的显示位置并重绘rabbit组件,最后将rabbit添加到布局管理器中,关键代码如下:
- FrameLayout frameLayout=(FrameLayout)findViewById(R.id.mylayout); //获取帧布局管理器
- final RabbitView rabbit=new RabbitView(MainActivity.this); //创建并实例化RabbitView类
- //为小兔子添加触摸事件监听器
- rabbit.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- rabbit.bitmapX=event.getX(); //设置小兔子显示位置的X坐标
- rabbit.bitmapY=event.getY(); //设置小兔子显示位置的Y坐标
- rabbit.invalidate(); //重绘rabbit组件
- return true;
- }
- });
- frameLayout.addView(rabbit); //将rabbit添加到布局管理器中
运行本实例,将显示如图3.7所示的运行结果。当用手指在屏幕上拖动时,小兔子将跟随手指的拖动轨迹移动。
图3.7 跟随手指的小兔子
3.2 布局管理器
教学录像:光盘\TM\lx\3\布局管理器.exe
在Android中,每个组件在窗体中都有具体的位置和大小,在窗体中摆放各种组件时,很难进行判断。不过,使用Android布局管理器可以很方便地控制各组件的位置和大小。Android中提供了线性布局管理器(LinearLayout)、表格布局管理器(TableLayout)、帧布局管理器(FrameLayout)、相对布局管理器(RelativeLayout)和绝对布局管理器(AbsoluteLayout),对应于这5种布局管理器,Android提供了5种布局方式,其中,绝对布局在Android 2.0中被标记为已过期,可以使用帧布局或相对布局替代,所以本节将只对前4种布局方式进行详细介绍。
3.2.1 线性布局
线性布局是将放入其中的组件按照垂直或水平方向来布局,也就是控制放入其中的组件横向或纵向排列。在线性布局中,每一行(针对垂直排列)或每一列(针对水平排列)中只能放一个组件,并且Android的线性布局不会换行,当组件排列到窗体的边缘后,后面的组件将不会被显示出来。
说明:在线性布局中,排列方式由android:orientation属性来控制,对齐方式由android:gravity属性来控制。
在Android中,可以在XML布局文件中定义线性布局管理器,也可以使用Java代码来创建(推荐使用前者)。在XML布局文件中定义线性布局管理器时,需要使用<LinearLayout>标记,其基本的语法格式如下:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- 属性列表
- >
- </LinearLayout>
在线性布局管理器中,常用的属性包括android:orientation、android:gravity、android:layout_width、android:layout_height、android:id和android:background。其中,前两个属性是线性布局管理器支持的属性,后面4个是android.view.View和android.view.ViewGroup支持的属性,下面进行详细介绍。
- android:orientation属性
android:orientation属性用于设置布局管理器内组件的排列方式,其可选值为horizontal和vertical,默认值为vertical。其中,horizontal表示水平排列;vertical表示垂直排列。
- android:gravity属性
android:gravity属性用于设置布局管理器内组件的对齐方式,其可选值包括top、bottom、left、right、center_vertical、fill_vertical、center_horizontal、fill_horizontal、center、fill、clip_vertical和clip_horizontal。这些属性值也可以同时指定,各属性值之间用竖线隔开。例如,要指定组件靠右下角对齐,可以使用属性值right|bottom。
- android:layout_width属性
android:layout_width属性用于设置组件的基本宽度,其可选值包括fill_parent、match_parent和wrap_content。其中,fill_parent表示该组件的宽度与父容器的宽度相同;match_paren与fill_parent的作用完全相同,从Android 2.2开始推荐使用;wrap_content表示该组件的宽度恰好能包裹它的内容。
说明:android:layout_width属性是ViewGroup.LayoutParams所支持的XML属性,对于其他的布局管理器同样适用。
- android:layout_height属性
android:layout_height属性用于设置组件的基本高度,其可选值包括fill_parent、match_parent和wrap_content。其中,fill_parent表示该组件的高度与父容器的高度相同;match_paren与fill_parent的作用完全相同,从Android 2.2开始推荐使用;wrap_content表示该组件的高度恰好能包裹它的内容。
说明:android:layout_height属性是ViewGroup.LayoutParams所支持的XML属性,对于其他的布局管理器同样适用。
- android:id属性
android:id属性用于为当前组件指定一个id属性,在Java代码中可以应用该属性单独引用这个组件。为组件指定id属性后,在R.java文件中,会自动派生一个对应的属性,在Java代码中,可以通过findViewById()方法来获取它。
- android:background属性
android:background属性用于为组件设置背景,可以是背景图片,也可以是背景颜色。为组件指定背景图片时,可以将准备好的背景图片复制到目录下,然后使用下面的代码进行设置:
- android:background="@drawable/background"
如果想指定背景颜色,可以使用颜色值。例如,要想指定背景颜色为白色,可以使用下面的代码:
- android:background="#FFFFFFFF"
说明:在线性布局中,还可以使用android.view.View类支持的其他属性,更加详细的内容可以参阅Android官方提供的API文档。
下面给出一个在程序中使用线性布局的实例。
例3.5 在Eclipse中创建Android项目,名称为3.5,实现采用线性布局显示一组按钮。(实例位置:光盘\TM\sl\3\3.5)
修改新建项目的res\layout目录下的布局文件main.xml,在默认添加的垂直线性布局管理器LinearLayout中添加4个按钮,并将每个按钮的android:layout_width属性值设置为match_parent。修改后的代码如下:
- <?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"
- android:background="@drawable/background"
- >
- <Button android:text="按钮1" android:id="@+id/button1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- <Button android:text="按钮2" android:id="@+id/button2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- <Button android:text="按钮3" android:id="@+id/button3"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- <Button android:text="按钮4" android:id="@+id/button4"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
- </LinearLayout>
运行本实例,将显示如图3.8所示的运行结果。
说明:在Android 4.0中,默认的情况下,按钮是半透明效果的,并不是图3.8所示的效果,为了达到图3.8的效果,需要在AndroidManifest.xml文件的<activity>标记中添加android:theme属性,并将属性值设置为@android:style/Theme.Black。
图3.8 垂直线性布局的效果
在本实例中,如果将android:orientation属性的值设置为horizontal,将采用水平线性布局。由于在水平线性布局中,当组件排列到窗体的边缘后,后面的组件将不会被显示出来,所以在窗体中将只显示“按钮1”,其他按钮不显示,为了让其他按钮也显示到窗体中,需要将各按钮的android:layout_width属性值和android:layout_height属性值互换,代码如下:
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
这时,再运行程序,将显示如图3.9所示的运行结果。
图3.9 水平线性布局的效果
3.2.2 表格布局
表格布局与常见的表格类似,以行、列的形式来管理放入其中的UI组件。表格布局使用<TableLayout>标记定义,在表格布局中,可以添加多个<TableRow>标记,每个<TableRow>标记占用一行。由于<TableRow>标记也是容器,所以还可在该标记中添加其他组件,每添加一个组件,表格就会增加一列。在表格布局中,列可以被隐藏,也可以被设置为伸展的,从而填充可利用的屏幕空间,还可以设置为强制收缩,直到表格匹配屏幕大小。
说明:如果在表格布局中,直接向<TableLayout>中添加UI组件,那么该组件将独占一行。
在Android中,可以在XML布局文件中定义表格布局管理器,也可以使用Java代码来创建。推荐使用前者。在XML布局文件中定义表格布局管理器的基本语法格式如下:
- <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
- 属性列表
- >
- <TableRow 属性列表> 需要添加的UI组件 </TableRow>
- 多个<TableRow>
- </TableLayout>
TableLayout继承了LinearLayout,因此它完全支持LinearLayout所支持的全部XML属性,此外,TableLayout还支持如表3.1所示的XML属性。
表3.1 TableLayout支持的XML属性
XML属性 | 描 述 |
android:collapseColumns | 设置需要被隐藏的列的列序号(序号从0开始),多个列序号之间用逗号“,”分隔 |
android:shrinkColumns | 设置允许被收缩的列的列序号(序号从0开始),多个列序号之间用逗号“,”分隔 |
android:stretchColumns | 设置允许被拉伸的列的列序号(序号从0开始),多个列序号之间用逗号“,”分隔 |
下面给出一个在程序中使用表格布局的实例。
例3.6 在Eclipse中创建Android项目,名称为3.6,应用表格布局实现用户登录界面。(实例位置:光盘\TM\sl\3\3.6)
修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的布局代码删除,然后添加一个TableLayout表格布局管理器,并且在该布局管理器中添加3个TableRow表格行,再在每个表格行中添加用户登录界面相关的组件,最后设置表格的第1列和第4列允许被拉伸。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <TableLayout android:id="@+id/tableLayout1"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@drawable/background_a"
- android:gravity="center_vertical"
- android:stretchColumns="0,3"
- >
- <!-- 第1行 -->
- <TableRow android:id="@+id/tableRow1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <TextView/>
- <TextView android:text="用户名:"
- android:id="@+id/textView1"
- android:layout_width="wrap_content"
- android:textSize="24px"
- android:layout_height="wrap_content"
- />
- <EditText android:id="@+id/editText1"
- android:textSize="24px"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:minWidth="200px"/>
- <TextView />
- </TableRow>
- <!-- 第2行 -->
- <TableRow android:id="@+id/tableRow2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <TextView/>
- <TextView android:text="密 码:"
- android:id="@+id/textView2"
- android:textSize="24px"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <EditText android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textSize="24px"
- android:id="@+id/editText2"
- android:inputType="textPassword"/>
- <TextView />
- </TableRow>
- <!-- 第3行 -->
- <TableRow android:id="@+id/tableRow3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <TextView/>
- <Button android:text="登录"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <Button android:text="退出"
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <TextView />
- </TableRow>
- </TableLayout>
说明:在本实例中,添加了6个TextView组件,并且设置对应列允许拉伸,这是为了让用户登录表单在水平方向上居中显示而设置的。
运行本实例,将显示如图3.10所示的运行结果。
图3.10 应用表格布局实现用户登录界面
3.2.3 帧布局
在帧布局管理器中,每加入一个组件,都将创建一个空白的区域,通常称为一帧,这些帧都会根据gravity属性执行自动对齐。默认情况下,帧布局从屏幕的左上角(0,0)坐标点开始布局,多个组件层叠排序,后面的组件覆盖前面的组件。
在Android中,可以在XML布局文件中定义帧布局管理器,也可以使用Java代码来创建。推荐使用前者。在XML布局文件中定义帧布局管理器可以使用<FrameLayout>标记,其基本的语法格式如下:
- < FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- 属性列表
- >
- </FrameLayout>
FrameLayout支持的常用XML属性如表3.2所示。
表3.2 FrameLayout支持的常用XML属性
XML属性 | 描 述 |
android:foreground | 设置该帧布局容器的前景图像 |
android:foregroundGravity | 定义绘制前景图像的gravity属性,即前景图像显示的位置 |
下面给出一个在程序中使用帧布局的实例。
例3.7 在Eclipse中创建Android项目,名称为3.7,应用帧布局居中显示层叠的正方形。(实例位置:光盘\TM\sl\3\3.7)
修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的布局代码删除,然后添加一个FrameLayout帧布局管理器,并且为其设置背景和前景,以及前景图像显示的位置,最后在该布局管理器中添加3个居中显示的TextView组件,并且为其指定不同的颜色和大小,以更好地体现层叠效果。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout
- android:id="@+id/frameLayout1"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@drawable/background"
- android:foreground="@drawable/icon"
- android:foregroundGravity="bottom|right"
- >
- <!-- 添加居中显示的红色背景的TextView,将显示在最下层 -->
- <TextView android:text="红色背景的TextView"
- android:id="@+id/textView1"
- android:background="#FFFF0000"
- android:layout_gravity="center"
- android:layout_width="400px"
- android:layout_height="400px"/>
- <!-- 添加居中显示的橙色背景的TextView,将显示在中间层 -->
- <TextView android:text="橙色背景的TextView"
- android:id="@+id/textView2"
- android:layout_width="300px"
- android:layout_height="300px"
- android:background="#FFFF6600"
- android:layout_gravity="center"
- />
- <!-- 添加居中显示的黄色背景的TextView,将显示在最上层 -->
- <TextView android:text="黄色背景的TextView"
- android:id="@+id/textView3"
- android:layout_width="200px"
- android:layout_height="200px"
- android:background="#FFFFEE00"
- android:layout_gravity="center"
- />
- </FrameLayout>
运行本实例,将显示如图3.11所示的运行结果。
图3.11 应用帧布局居中显示层叠的正方形
说明:帧布局经常应用在游戏开发中,用于显示自定义的视图。例如,在3.1.4节的例3.4中,实现跟随手指的小兔子时就应用了帧布局。
3.2.4 相对布局
相对布局是指按照组件之间的相对位置来进行布局,如某个组件在另一个组件的左边、右边、上方或下方等。
在Android中,可以在XML布局文件中定义相对布局管理器,也可以使用Java代码来创建。推荐使用前者。在XML布局文件中定义相对布局管理器可以使用<RelativeLayout>标记,其基本的语法格式如下:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- 属性列表
- >
- </RelativeLayout>
RelativeLayout支持的常用XML属性如表3.3所示。
表3.3 RelativeLayout支持的常用XML属性
XML属性 | 描 述 |
android:gravity | 用于设置布局管理器中各子组件的对齐方式 |
android:ignoreGravity | 用于指定哪个组件不受gravity属性的影响 |
在相对布局管理器中,只有上面介绍的两个属性是不够的,为了更好地控制该布局管理器中各子组件的布局分布,RelativeLayout提供了一个内部类RelativeLayout.LayoutParams,通过该类提供的大量XML属性,可以很好地控制相对布局管理器中各组件的分布方式。RelativeLayout.LayoutParams支持的XML属性如表3.4所示。
表3.4 RelativeLayout.LayoutParams支持的常用XML属性
XML属性 | 描 述 |
android:layout_above | 其属性值为其他UI组件的id属性,用于指定该组件位于哪个组件的上方 |
android:layout_alignBottom | 其属性值为其他UI组件的id属性,用于指定该组件与哪个组件的下边界对齐 |
android:layout_alignLeft | 其属性值为其他UI组件的id属性,用于指定该组件与哪个组件的左边界对齐 |
android:layout_alignParentBottom | 其属性值为boolean值,用于指定该组件是否与布局管理器底端对齐 |
android:layout_alignParentLeft | 其属性值为boolean值,用于指定该组件是否与布局管理器左边对齐 |
android:layout_alignParentRight | 其属性值为boolean值,用于指定该组件是否与布局管理器右边对齐 |
android:layout_alignParentTop | 其属性值为boolean值,用于指定该组件是否与布局管理器顶端对齐 |
android:layout_alignRight | 其属性值为其他UI组件的id属性,用于指定该组件与哪个组件的右边界对齐 |
android:layout_alignTop | 其属性值为其他UI组件的id属性,用于指定该组件与哪个组件的上边界对齐 |
android:layout_below | 其属性值为其他UI组件的id属性,用于指定该组件位于哪个组件的下方 |
android:layout_centerHorizontal | 其属性值为boolean值,用于指定该组件是否位于布局管理器水平居中的位置 |
android:layout_centerInParent | 其属性值为boolean值,用于指定该组件是否位于布局管理器的中央位置 |
android:layout_centerVertical | 其属性值为boolean值,用于指定该组件是否位于布局管理器垂直居中的位置 |
android:layout_toLeftOf | 其属性值为其他UI组件的id属性,用于指定该组件位于哪个组件的左侧 |
android:layout_toRightOf | 其属性值为其他UI组件的id属性,用于指定该组件位于哪个组件的右侧 |
下面给出一个在程序中使用相对布局的实例。
例3.8 在Eclipse中创建Android项目,名称为3.8,应用相对布局实现显示软件更新提示界面。(实例位置:光盘\TM\sl\3\3.8)
修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的布局代码删除,然后添加一个RelativeLayout相对布局管理器,并且为其设置背景,最后在该布局管理器中添加一个TextView和两个Button,并设置它们的显示位置及对齐方式。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- android:id="@+id/relativeLayout1"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:background="@drawable/background"
- >
- <!-- 添加一个居中显示的文本视图textView1 -->
- <TextView android:text="发现有Widget的新版本,您想现在就安装吗?"
- android:id="@+id/textView1"
- android:textSize="24px"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_centerInParent="true"
- />
- <!-- 添加一个在button2左侧显示的按钮button1 -->
- <Button
- android:text="现在更新"
- android:id="@+id/button1"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_below="@+id/textView1"
- android:layout_toLeftOf="@+id/button2"
- />
- <!-- 添加一个按钮button2,该按钮与textView1的右边界对齐 -->
- <Button
- android:text="以后再说"
- android:id="@+id/button2"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignRight="@+id/textView1"
- android:layout_below="@+id/textView1"
- />
- </RelativeLayout>
说明:在上面的代码中,将文本视图textView1设置为在屏幕中央显示,然后设置按钮button2在textView1的下方并与其右边界对齐,最后设置按钮button1在button2的左侧显示。
运行本实例,将显示如图3.12所示的运行结果。
图3.12 应用相对布局显示软件更新提示
3.2.5 范例1:使用表格布局与线性布局实现分类工具栏
例3.9 在Eclipse中创建Android项目,名称为3.9,应用表格布局和线性布局分类显示快捷工具栏。(实例位置:光盘\TM\sl\3\3.9)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的布局代码删除,然后添加一个TableLayout表格布局管理器,并且在该布局管理器中添加3个TableRow表格行,并将这3个表格行的android:layout_weight属性值均设置为1,表示这3行平均分配整个视图空间,也就是每行占据整个屏幕1/3的空间。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <TableLayout
- android:id="@+id/tableLayout1"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/background"
- android:padding="10px"
- xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- 第1行 -->
- <TableRow
- android:id="@+id/tableRow1"
- android:layout_width="fill_parent"
- android:layout_weight="1">
- </TableRow>
- <!-- 第2行 -->
- <TableRow
- android:id="@+id/tableRow2"
- android:layout_width="fill_parent"
- android:layout_weight="1">
- </TableRow>
- <!-- 第3行 -->
- <TableRow
- android:id="@+id/tableRow3"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/blockbg_big">
- </TableRow>
- </TableLayout>
(2)在第1个表格行中添加具体的内容。首先添加两个水平方向的线性布局管理器,并且设置这两个线性布局管理器各占行宽的1/2,然后在第1个线性布局管理器中添加1个TextView组件,并设置为居中显示,用于显示日期和时间,接下来在第2个线性布局管理器中添加3个ImageView组件,并设置这3个ImageView组件平均分配其父视图中的可用空间,用于显示快捷图标,最后为第2个线性布局管理器设置内边距,并设置各ImageView组件的左外边距。具体代码如下:
- <LinearLayout
- android:id="@+id/linearLayout1"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/blockbg_big">
- <TextView
- android:id="@+id/textView1"
- android:text="@string/time"
- style="@style/text"
- android:layout_width="fill_parent"
- android:gravity="center"
- android:layout_height="fill_parent" />
- </LinearLayout>
- <LinearLayout
- android:id="@+id/linearLayout2"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/blockbg_big"
- android:padding="40px">
- <ImageView
- android:src="@drawable/img01"
- android:id="@+id/imageView1"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- <ImageView
- android:src="@drawable/img02"
- android:id="@+id/imageView2"
- android:layout_weight="1"
- android:layout_marginLeft="50px"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- <ImageView
- android:src="@drawable/img03a"
- android:id="@+id/imageView3"
- android:layout_weight="1"
- android:layout_marginLeft="50px"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- </LinearLayout>
(3)在第2个表格行中添加具体的内容。首先添加两个水平方向的线性布局管理器,并且设置这两个线性布局管理器各占行宽的1/2,然后在第1个线性布局管理器中添加3个ImageView组件,并设置这3个ImageView平均分配其父视图中的可用空间,用于显示快捷图标,接下来在第2个线性布局管理器中添加一个ImageView组件和一个TextView组件,并设置ImageView组件占其父视图可用空间的1/4,TextView组件占其父视图可用空间的3/4,用于显示“转到音乐”工具栏,最后为这两个线性布局管理器设置内边距,并设置各ImageView组件的外边距。具体代码如下:
- <LinearLayout
- android:id="@+id/linearLayout3"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/blockbg_big"
- android:padding="40px">
- <ImageView
- android:src="@drawable/img04"
- android:id="@+id/imageView4"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- <ImageView
- android:src="@drawable/img05"
- android:id="@+id/imageView5"
- android:layout_weight="1"
- android:layout_marginLeft="40px"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- <ImageView
- android:src="@drawable/img06"
- android:id="@+id/imageView6"
- android:layout_weight="1"
- android:layout_marginLeft="40px"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- </LinearLayout>
- <LinearLayout
- android:id="@+id/linearLayout4"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/blockbg_big">
- <ImageView
- android:src="@drawable/img07"
- android:id="@+id/imageView7"
- android:layout_weight="1"
- android:layout_margin="40px"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- <TextView
- android:id="@+id/textView2"
- android:text="转到音乐"
- android:gravity="center_vertical"
- style="@style/text"
- android:layout_weight="3"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- </LinearLayout>
(4)在第3个表格行中添加具体的内容。首先添加一个水平方向的线性布局管理器,然后在该布局管理器中添加一个ImageView组件和一个TextView组件,并设置这两个组件及线性布局管理器的左外边距,最后设置TextView组件垂直居中显示。具体代码如下:
- <LinearLayout
- android:id="@+id/linearLayout5"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:layout_marginLeft="20px">
- <ImageView
- android:src="@drawable/email"
- android:id="@+id/imageView8"
- android:layout_marginLeft="20px"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- <TextView android:id="@+id/textView2"
- android:text="电子邮件"
- android:layout_marginLeft="20px"
- android:gravity="center_vertical"
- style="@style/text"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent" />
- </LinearLayout>
运行本实例,将显示如图3.13所示的运行结果。
图3.13 布局分类显示的快捷工具栏
3.2.6 范例2:布局个性游戏开始界面
例3.10 在Eclipse中创建Android项目,名称为3.10,应用线性布局和相对布局实现个性游戏开始界面。(实例位置:光盘\TM\sl\3\3.10)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的布局代码中的TextView组件删除,然后添加一个ImageView组件,用于显示顶部图片,并设置其缩放方式为保持纵横比缩放,让图片完全覆盖ImageView。修改后的代码如下:
- <?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">
- <!-- 添加顶部图片 -->
- <ImageView android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:scaleType="centerCrop"
- android:layout_weight="1"
- android:src="@drawable/top" />
- </LinearLayout>
(2)在ImageView组件的下方添加一个相对布局管理器,用于显示控制按钮。在该布局管理器中添加5个ImageView组件,并且第1个ImageView组件显示在相对布局管理器的中央,其他4个环绕在第1个组件的四周,具体代码如下:
- <!-- 添加一个相对布局管理器 -->
- <RelativeLayout android:layout_weight="2"
- android:layout_height="wrap_content"
- android:background="@drawable/bottom"
- android:id="@+id/relativeLayout1"
- android:layout_width="match_parent">
- <!-- 添加中间位置的图片按钮 -->
- <ImageView android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/imageButton0"
- android:src="@drawable/in"
- android:layout_centerlnParent="true"/>
- <!-- 添加上方显示的图片 -->
- <ImageView android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/imageButton1"
- android:src="@drawable/setting"
- android:layout_above="@+id/imageButton0"
- android:layout_alignRight="@+id/imageButton0"/>
- <!-- 添加下方显示的图片 -->
- <ImageView android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/imageButton2"
- android:src="@drawable/exit"
- android:layout_below="@+id/imageButton0"
- android:layout_alignLeft="@+id/imageButton0"/>
- <!-- 添加左侧显示的图片-->
- <ImageView android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/imageButton3"
- android:src="@drawable/help"
- android:layout_toLeftOf="@+id/imageButton0"
- android:layout_alignTop="@+id/imageButton0"/>
- <!-- 添加右侧显示的图片 -->
- <ImageView android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/imageButton4"
- android:src="@drawable/board"
- android:layout_toRightOf="@+id/imageButton0"
- android:layout_alignTop="@+id/imageButton0"/>
- </RelativeLayout>
(3)在主活动中,获取各ImageView组件代表的按钮,并为各按钮添加单击事件监听器。例如,为“进入”按钮添加单击事件监听器,代码如下:
- //为“进入”按钮添加单击事件监听器
- ImageView img0=(ImageView)findViewById(R.id.imageButton0);
- img0.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Toast.makeText(MainActivity.this, "进入游戏", Toast.LENGTH_SHORT).show();
- }
- });
说明:为其他按钮添加单击事件监听器的方法与“进入”按钮相同,这里不再赘述。
运行本实例,将显示如图3.14所示的运行结果。
图3.14 布局个性游戏开始界面
3.3 基本组件
教学录像:光盘\TM\lx\3\基本组件.exe
Android应用程序的人机交互界面由很多Android组件组成。例如,在前面两节中使用的TextView和ImageView都是Android提供的组件。本节将对Android提供的基本组件进行详细介绍。
3.3.1 文本框与编辑框
Android中提供了两种文本组件:一种是文本框(TextView),用于在屏幕上显示文本;另一种是编辑框(EditText),用于在屏幕上显示可编辑的文本框。其中,EditText是TextView类的子类。下面分别对文本框和编辑框进行介绍。
- 文本框
在Android中,文本框使用TextView表示,用于在屏幕上显示文本。与Java中的文本框组件不同,Text View相当于Java中的标签,也就是JLable。需要说明的是,Android中的文本框组件可以显示单行文本,也可以显示多行文本,还可以显示带图像的文本。
在Android中,可以使用两种方法向屏幕中添加文本框:一种是通过在XML布局文件中使用<TextView>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法,也就是通过<TextView>标记在XML布局文件中添加文本框,其基本的语法格式如下:
- <TextView
- 属性列表
- >
- </TextView>
TextView支持的常用XML属性如表3.5所示。
表3.5 TextView支持的XML属性
XML属性 | 描 述 |
android:autoLink | 用于指定是否将指定格式的文本转换为可单击的超链接形式,其属性值有none、web、email、phone、map和all |
android:drawableBottom | 用于在文本框内文本的底端绘制指定图像,该图像可以是放在res\drawable目录下的图片,通过“@drawable/文件名(不包括文件的扩展名)”设置 |
android:drawableLeft | 用于在文本框内文本的左侧绘制指定图像,该图像可以是放在res\drawable目录下的图片,通过“@drawable/文件名(不包括文件的扩展名)”设置 |
android:drawableRight | 用于在文本框内文本的右侧绘制指定图像,该图像可以是放在res\drawable目录下的图片,通过“@drawable/文件名(不包括文件的扩展名)”设置 |
android:drawableTop | 用于在文本框内文本的顶端绘制指定图像,该图像可以是放在res\drawable目录下的图片,通过“@drawable/文件名(不包括文件的扩展名)”设置 |
android:gravity | 用于设置文本框内文本的对齐方式,可选值有top、bottom、left、right、center_vertical、fill_vertical、center_horizontal、fill_horizontal、center、fill、clip_vertical和clip_horizontal等。这些属性值也可以同时指定,各属性值之间用竖线隔开。例如,要指定组件靠右下角对齐,可以使用属性值right|bottom |
android:hint | 用于设置当文本框中文本内容为空时,默认显示的提示文本 |
android:inputType | 用于指定当前文本框显示内容的文本类型,其可选值有textPassword、textEmailAddress、phone和date等,可以同时指定多个,使用“|”分隔 |
android:singleLine | 用于指定该文本框是否为单行模式,其属性值为true或false,为true表示该文本框不会换行,当文本框中的文本超过一行时,其超出的部分将被省略,同时在结尾处添加“…” |
android:text | 用于指定该文本中显示的文本内容,可以直接在该属性值中指定,也可以通过在strings.xml文件中定义文本常量的方式指定 |
android:textColor | 用于设置文本框内文本的颜色,其属性值可以是#rgb、#argb、#rrggbb或#aarrggbb格式指定的颜色值 |
android:textSize | 用于设置文本框内文本的字体大小,其属性由代表大小的数值和单位组成,其单位可以是px、pt、sp和in等 |
android:width | 用于指定文本的宽度,以像素为单位 |
android:height | 用于指定文本的高度,以像素为单位 |
说明:在表3.5中,只给出了TextView组件常用的部分属性,关于该组件的其他属性,可以参阅Android官方提供的API文档。
下面给出一个关于文本框的实例。
例3.11 在Eclipse中创建Android项目,名称为3.11,实现为文本框中的E-mail地址添加超链接、显示带图像的文本、显示不同颜色的单行文本和多行文本。(实例位置:光盘\TM\sl\3\3.11)
(1)修改新建项目的res\layout目录下的布局文件main.xml,为默认添加的LinearLayout垂直线性布局管理器设置背景,并为默认添加的TextView组件设置高度和对其中的E-mail格式的文本设置超链接,修改后的代码如下:
- <?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"
- android:background="@drawable/background">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- android:autoLink="email"
- android:height="50px"/>
- </LinearLayout>
(2)在默认添加的TextView组件后面添加一个TextView组件,设置该组件显示带图像的文本(图像在文字的上方),具体代码如下:
- <TextView
- android:layout_width="wrap_content"
- android:id="@+id/textView1"
- android:text="带图片的TextView"
- android:drawableTop="@drawable/icon"
- android:layout_height="wrap_content" />
(3)在步骤(2)添加的TextView组件的后面添加两个TextView组件,一个设置为可以显示多行文本(默认的),另一个设置为只能显示单行文本,并将这两个TextView组件设置为不同颜色,具体代码如下:
- <TextView
- android:id="@+id/textView2"
- android:textColor="#0f0"
- android:textSize="20px"
- android:text="多行文本:在很久很久以前,有一位老人他带给我们一个苹果"
- android:width="300px"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
- <TextView
- android:id="@+id/textView3"
- android:textColor="#f00"
- android:textSize="20px"
- android:text="单行文本:在很久很久以前,有一位老人他带给我们一个苹果"
- android:width="300px"
- android:singleLine="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
运行本实例,将显示如图3.15所示的运行结果。
图3.15 应用TextView显示多种样式的文本
- 编辑框
在Android中,编辑框使用EditText表示,用于在屏幕上显示文本输入框,这与Java中的文本框组件功能类似。需要说明的是,Android中的编辑框组件可以输入单行文本,也可以输入多行文本,还可以输入指定格式的文本(如密码、电话号码、E-mail地址等)。
在Android中,可以使用两种方法向屏幕中添加编辑框:一种是通过在XML布局文件中使用<EditText>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法,也就是通过<EditText>标记在XML布局文件中添加编辑框,其基本的语法格式如下:
- <EditText
- 属性列表
- >
- </EditText>
由于EditText类是TextView的子类,所以对于表3.5中列出的XML属性,同样适用于EditText组件。需要特别注意的是,在EditText组件中,android:inputType属性可以帮助输入框显示合适的类型。例如,要添加一个密码框,可以将android:inputType属性设置为textPassword。
技巧:在Eclipse中,打开布局文件,通过Graphical Layout视图,可以在可视化界面中通过拖曳的方式添加编辑框组件,并且在可视化界面中还列出了不同类型的输入框(如密码框、数字密码框和输入电话号码的编辑框等),只需要将其拖曳到布局文件中即可。
在屏幕中添加编辑框后,还需要获取编辑框中输入的内容,这可以通过编辑框组件提供的getText()方法实现。使用该方法时,先要获取到编辑框组件,然后再调用getText()方法。例如,要获取布局文件中添加的id属性为login的编辑框的内容,可以通过以下代码实现:
- EditText login=(EditText)findViewById(R.id.login);
- String loginText=login.getText().toString();
下面给出一个关于编辑框的实例。
例3.12 在Eclipse中创建Android项目,名称为3.12,实现会员注册界面。(实例位置:光盘\TM\ sl\3\3.12)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的布局代码删除,然后添加一个TableLayout表格布局管理器,并且在该布局管理器中添加4个TableRow表格行,并为该表格布局管理器设置背景。修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/tableLayout1"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/background">
- <TableRow android:id="@+id/tableRow1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"> </TableRow>
- …… <!-- 省略了第2个和第3个表格行的代码 -->
- <TableRow android:id="@+id/tableRow4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"> </TableRow>
- </TableLayout>
(2)在表格的第1行,添加一个用于显示提示信息的文本框和一个输入会员昵称的单行编辑框,并为该单行编辑框设置提示文本,具体代码如下:
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="texnickname"
- android:text="会员昵称:"
- android:height="50px" />
- <EditText android:id="@+id/nickname"
- android:hint="请输入会员昵称"
- android:layout_width="300px"
- android:layout_height="wrap_content"
- android:singleLine="true"
- />
(3)在表格的第2行,添加用于显示提示信息的文本框和一个输入密码的密码框,具体代码如下:
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="textPassword"
- android:text="输入密码:"
- android:height="50px" />
- <EditText android:id="@+id/pwd"
- android:layout_width="300px"
- android:inputType="textPassword"
- android:layout_height="wrap_content"
- />
(4)在表格的第3行,按照步骤(3)的方法添加一个确认密码的密码框,其具体的实现代码与步骤(3)类似,这里不再赘述。
(5)在表格的第4行,添加用于显示提示信息的文本框和一个输入E-mail地址的编辑框,具体代码如下:
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:inputType="textEmailAddress"
- android:text="E-mail:"
- android:height="50px" />
- <EditText android:id="@+id/email"
- android:layout_width="300px"
- android:layout_height="wrap_content"
- android:inputType="textEmailAddress"
- />
(6)添加一个水平线性布局管理器,并在该布局管理器中添加两个按钮,具体代码如下:
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <Button android:text="注册"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <Button android:text="重置"
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- </LinearLayout>
(7)在主活动的onCreate()方法中,为“注册”按钮添加单击事件监听器,用于在用户单击“注册”按钮后,在日志面板(LogCat)中显示输入的内容,关键代码如下:
- Button button1=(Button)findViewById(R.id.button1);
- button1.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- EditText nicknameET=(EditText)findViewById(R.id.nickname); //获取会员昵称编辑框组件
- String nickname=nicknameET.getText().toString(); //获取输入的会员昵称
- EditText pwdET=(EditText)findViewById(R.id.pwd); //获取密码编辑框组件
- String pwd=pwdET.getText().toString(); //获取输入的密码
- EditText emailET=(EditText)findViewById(R.id.email); //获取E-mail编辑框组件
- String email=emailET.getText().toString(); //获取输入的E-mail地址
- Log.i("编辑框的应用","会员昵称:"+nickname);
- Log.i("编辑框的应用","密码:"+pwd);
- Log.i("编辑框的应用","E-mail地址:"+email);
- }
- });
运行本实例,在屏幕中将显示“会员昵称”和“输入密码”等编辑框,输入如图3.16所示的内容后,单击“注册”按钮,将在日志中显示如图3.17所示的内容。
![]() | ![]() |
图3.16 应用EditText实现会员注册界面 | 图3.17 在日志面板中显示的编辑框中输入的内容 |
3.3.2 按钮
Android中提供了普通按钮和图片按钮两种按钮组件。这两种按钮组件都用于在UI界面上生成一个可以单击的按钮。当用户单击按钮时,将会触发一个onClick事件,可以通过为按钮添加单击事件监听器指定所要触发的动作。下面分别对普通按钮和图片按钮进行详细介绍。
- 普通按钮
在Android中,可以使用两种方法向屏幕中添加按钮:一种是通过在XML布局文件中使用<Button>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法,也就是通过<Button>标记在XML布局文件中添加普通按钮,其基本的语法格式如下:
- <Button
- android:text="显示文本"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- </Button>
在屏幕上添加按钮后,还需要为按钮添加单击事件监听器,才能让按钮发挥其特有的用途。Android提供了两种为按钮添加单击事件监听器的方法,一种是在Java代码中完成,例如,在Activity的onCreate()方法中完成,具体的代码如下:
- import android.view.View.OnClickListener;
- import android.widget.Button;
- Button login=(Button)findViewById(R.id.login); //通过ID获取布局文件中添加的按钮
- login.setOnClickListener(new OnClickListener() { //为按钮添加单击事件监听器
- @Override
- public void onClick(View v) {
- //编写要执行的动作代码
- }
- });
另一种是在Activity中编写一个包含View类型参数的方法,并且将要触发的动作代码放在该方法中,然后在布局文件中,通过android:onClick属性指定对应的方法名实现。例如,在Activity中编写一个名为myClick()的方法,关键代码如下:
- public void myClick(View view){
- //编写要执行的动作代码
- }
那么就可以在布局文件中通过android:onClick="myClick"语句为按钮添加单击事件监听器。
- 图片按钮
图片按钮与普通按钮的使用方法基本相同,只不过图片按钮使用<ImageButton>标记定义,并且可以为其指定android:src属性,用于设置要显示的图片。在布局文件中添加图像按钮的基本语法格式如下:
- <ImageButton
- android:id="@+id/imageButton1"
- android:src="@drawable/图片文件名"
- android:background="#000"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- </ImageButton>
同普通按钮一样,也需要为图片按钮添加单击事件监听器,具体添加方法同普通按钮,这里不再赘述。
下面给出一个关于按钮的实例。
例3.13 在Eclipse中创建Android项目,名称为3.13,实现添加普通按钮和图片按钮并为其设置单击事件监听器。(实例位置:光盘\TM\sl\3\3.13)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的垂直线性布局管理器设置为水平线性布局管理器,在该布局管理器中添加一个普通按钮(id属性为login)和一个图片按钮,并为图片按钮设置android:src属性、android:background属性和android:onClick属性,具体代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <Button android:text="登录"
- android:id="@+id/login"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <ImageButton
- android:id="@+id/login1"
- android:layout_width="wrap_content"
- android:src="@drawable/login"
- android:onClick="myClick"
- android:background="#000"
- android:layout_height="wrap_content">
- </ImageButton>
- </LinearLayout>
(2)在主活动MainActivity的onCreate()方法中,应用下面的代码为普通按钮添加单击事件监听器。
- Button login=(Button)findViewById(R.id.login); //通过ID获取布局文件中添加的按钮
- login.setOnClickListener(new OnClickListener() { //为按钮添加单击事件监听器
- @Override
- public void onClick(View v) {
- Toast toast=Toast.makeText(MainActivity.this, "您单击了普通按钮", Toast.LENGTH_SHORT);
- toast.show(); //显示提示信息
- }
- });
(3)在MainActivity类中编写一个方法myClick(),用于指定将要触发的动作代码,具体代码如下:
- public void myClick(View view){
- Toast toast=Toast.makeText(MainActivity.this, "您单击了图片按钮", Toast.LENGTH_SHORT);
- toast.show(); //显示提示信息
- }
运行本实例,将显示如图3.18所示的运行结果,单击普通按钮,将显示“您单击了普通按钮”的提示信息;单击图片按钮,将显示“您单击了图片按钮”的提示信息。
图3.18 添加普通按钮和图片按钮
3.3.3 单选按钮和复选框
在Android中,单选按钮和复选框都继承了普通按钮,因此,它们都可以直接使用普通按钮支持的各种属性和方法。与普通按钮不同的是,它们提供了可选中的功能。下面分别对单选按钮和复选框进行详细介绍。
- 单选按钮
在默认情况下,单选按钮显示为一个圆形图标,并且在该图标旁边放置一些说明性文字。在程序中,一般将多个单选按钮放置在按钮组中,使这些单选按钮表现出某种功能,当用户选中某个单选按钮后,按钮组中的其他按钮将被自动取消选中状态。在Android中,单选按钮使用RadioButton表示,而RadioButton类又是Button的子类,所以单选按钮可以直接使用Button支持的各种属性。
在Android中,可以使用两种方法向屏幕中添加单选按钮:一种是通过在XML布局文件中使用<RadioButton>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法,也就是通过<RadioButton>在XML布局文件中添加单选按钮,其基本语法格式如下:
- <RadioButton
- android:text="显示文本"
- android:id="@+id/ID号"
- android:checked="true|false"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- </RadioButton>
RadioButton组件的android:checked属性用于指定选中状态,属性值为true时,表示选中;属性值为false时,表示取消选中,默认为false。
通常情况下,RadioButton组件需要与RadioGroup组件一起使用,组成一个单选按钮组。在XML布局文件中,添加RadioGroup组件的基本格式如下:
- <RadioGroup
- android:id="@+id/radioGroup1"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <!-- 添加多个RadioGroup组件 -->
- </RadioGroup>
例3.14 在Eclipse中创建Android项目,名称为3.14,实现在屏幕上添加选择性别的单选按钮组。(实例位置:光盘\TM\sl\3\3.14)
修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的垂直线性布局管理器设置为水平布局管理器,在该布局管理器中添加一个TextView组件、一个包含两个单选按钮的单选按钮组和一个用于提交的按钮,具体代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/background">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="性别:"
- android:height="50px" />
- <RadioGroup
- android:id="@+id/radioGroup1"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <RadioButton
- android:layout_height="wrap_content"
- android:id="@+id/radio0"
- android:text="男"
- android:layout_width="wrap_content"
- android:checked="true"/>
- <RadioButton
- android:layout_height="wrap_content"
- android:id="@+id/radio1"
- android:text="女"
- android:layout_width="wrap_content"/>
- </RadioGroup>
- <Button android:text="提交" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_ height="wrap_content"></Button>
- </LinearLayout>
运行本实例,将显示如图3.19所示的运行结果。
图3.19 添加选择性别的单选按钮组
在屏幕中添加单选按钮组后,还需要获取单选按钮组中选中项的值,通常存在以下两种情况:一种是在改变单选按钮组的值时获取;另一种是在单击其他按钮时获取。下面分别介绍这两种情况所对应的实现方法。
[√]在改变单选按钮组的值时获取
在改变单选按钮组的值时获取选中项的值时,首先需要获取单选按钮组,然后为其添加OnCheckedChangeListener,并在其onCheckedChanged()方法中根据参数checkedId获取被选中的单选按钮,并通过其getText()方法获取该单选按钮对应的值。例如,要获取id属性为radioGroup1的单选按钮组的值,可以通过下面的代码实现。
- RadioGroup sex=(RadioGroup)findViewById(R.id.radioGroup1);
- sex.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- RadioButton r=(RadioButton)findViewById(checkedId);
- r.getText(); //获取被选中的单选按钮的值
- }
- });
[√]单击其他按钮时获取
单击其他按钮时获取选中项的值时,首先需要在该按钮的单击事件监听器的onClick()方法中,通过for循环语句遍历当前单选按钮组,并根据被遍历到的单选按钮的isChecked()方法判断该按钮是否被选中,当被选中时,通过单选按钮的getText()方法获取对应的值。例如,要在单击“提交”按钮时,获取id属性为radioGroup1的单选按钮组的值,可以通过下面的代码实现。
- final RadioGroup sex=(RadioGroup)findViewById(R.id.radioGroup1);
- Button button=(Button)findViewById(R.id.button1); //获取一个提交按钮
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- for(int i=0;i<sex.getChildCount();i++){
- RadioButton r=(RadioButton)sex.getChildAt(i); //根据索引值获取单选按钮
- if(r.isChecked()){ //判断单选按钮是否被选中
- r.getText(); //获取被选中的单选按钮的值
- break; //跳出for循环
- }
- }
- }
- });
下面以例3.14中介绍的实例为例,具体说明如何获取单选按钮组的值。首先打开例3.14中的主活动MainActivity,然后在onCreate()方法中编写获取单选按钮组的值的代码。这里,通过以下两种方式来完成。
(1)在改变单选按钮组的值时获取
获取单选按钮组,并为其添加事件监听器,在该事件监听器的onCheckedChanged()方法中获取被选择的单选按钮的值,并输出到日志中,具体代码如下:
- final RadioGroup sex = (RadioGroup) findViewById(R.id.radioGroup1); //获取单选按钮组
- //为单选按钮组添加事件监听器
- sex.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- RadioButton r = (RadioButton) findViewById(checkedId); //获取被选择的单选按钮
- Log.i("单选按钮", "您的选择是:" + r.getText());
- }
- });
(2)单击“提交”按钮时获取
获取“提交”按钮,并为“提交”按钮添加单击事件监听器,在重写的onClick()方法中通过for循环遍历单选按钮组,并获取到被选择项,具体代码如下:
- Button button = (Button) findViewById(R.id.button1); //获取提交按钮
- //为“提交”按钮添加单击事件监听器
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //通过for循环遍历单选按钮组
- for (int i = 0; i < sex.getChildCount(); i++) {
- RadioButton r = (RadioButton) sex.getChildAt(i);
- if (r.isChecked()) { //判断单选按钮是否被选中
- Log.i("单选按钮", "性别:" + r.getText());
- break; //跳出for循环
- }
- }
- }
- });
这时,再次运行例3.14,选中单选按钮“女”后,单击“提交”按钮,在日志面板中将显示如图3.20所示的内容。
图3.20 在日志面板中显示获取到的单选按钮的值
- 复选框
在默认情况下,复选框显示为一个方块图标,并且在该图标旁边放置一些说明性文字。与单选按钮唯一不同的是,复选框可以进行多选设置,每一个复选框都提供“选中”和“不选中”两种状态。在Android中,复选框使用CheckBox表示,而CheckBox类又是Button的子类,所以可以直接使用Button支持的各种属性。
在Android中,可以使用两种方法向屏幕中添加复选框:一种是通过在XML布局文件中使用<CheckBox>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法,也就是通过<CheckBox>在XML布局文件中添加复选框,其基本语法格式如下:
- <CheckBox android:text="显示文本"
- android:id="@+id/ID号"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- </CheckBox>
由于使用复选框可以选中多项,所以为了确定用户是否选择了某一项,还需要为每一个选项添加事件监听器。例如,要为id为like1的复选框添加状态改变事件监听器,可以使用下面的代码:
- final CheckBox like1=(CheckBox)findViewById(R.id.like1); //根据id属性获取复选框
- like1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if(like1.isChecked()){ //判断该复选框是否被选中
- like1.getText(); //获取选中项的值
- }
- }
- });
例3.15 在Eclipse中创建Android项目,名称为3.15,实现在屏幕上添加选择爱好的复选框,并获取选择的值。(实例位置:光盘\TM\sl\3\3.15)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的垂直线性布局管理器设置为水平线性布局管理器,在该布局管理器中添加一个TextView组件、3个复选框和一个提交按钮,关键代码如下:
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="爱好:"
- android:width="100px"
- android:gravity="right"
- android:height="50px" />
- <CheckBox android:text="体育"
- android:id="@+id/like1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <CheckBox android:text="音乐"
- android:id="@+id/like2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <CheckBox android:text="美术"
- android:id="@+id/like3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <Button android:text="提交" android:id="@+id/button1" android:layout_width="wrap_content" android: layout_height= "wrap_content"></Button>
(2)在主活动中创建并实例化一个OnCheckedChangeListener对象,在实例化该对象时,重写onCheckedChanged()方法,当复选框被选中时,输出一条日志信息,显示被选中的复选框,具体代码如下:
- //创建一个状态改变监听对象
- private OnCheckedChangeListener checkBox_listener=new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if(isChecked){ //判断复选框是否被选中
- Log.i("复选框","选中了["+buttonView.getText().toString()+"]");
- }
- }
- };
(3)在主活动的onCreate()方法中获取添加的3个复选框,并为每个复选框添加状态改变事件监听器,关键代码如下:
- final CheckBox like1=(CheckBox)findViewById(R.id.like1); //获取第1个复选框
- final CheckBox like2=(CheckBox)findViewById(R.id.like2); //获取第2个复选框
- final CheckBox like3=(CheckBox)findViewById(R.id.like3); //获取第3个复选框
- like1.setOnCheckedChangeListener(checkBox_listener); //为like1添加状态改变监听器
- like2.setOnCheckedChangeListener(checkBox_listener); //为like2添加状态改变监听器
- like3.setOnCheckedChangeListener(checkBox_listener); //为like3添加状态改变监听器
(4)获取“提交”按钮,并为“提交”按钮添加单击事件监听器,在该事件监听器的onClick()方法中通过if语句获取被选中的复选框的值,并通过一个提示信息框显示,具体代码如下:
- //为“提交”按钮添加单击事件监听器
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String like=""; //保存选中的值
- if(like1.isChecked()) //当第1个复选框被选中
- like+=like1.getText().toString()+" ";
- if(like2.isChecked()) //当第2个复选框被选中
- like+=like2.getText().toString()+" ";
- if(like3.isChecked()) //当第3个复选框被选中
- like+=like3.getText().toString()+" ";
- Toast.makeText(MainActivity.this, like, Toast.LENGTH_SHORT).show(); //显示被选中的复选框
- }
- });
运行本实例,将显示3个用于选择爱好的复选框,选取其中的“体育”和“美术”复选框,如图3.21所示,单击“提交”按钮,将显示如图3.22所示的提示信息框。
![]() | ![]() |
图3.21 添加选择爱好的复选框 | 图3.22 显示的提示信息框 |
3.3.4 图像视图
图像视图(ImageView),用于在屏幕中显示任何Drawable对象,通常用来显示图片。在Android中,可以使用两种方法向屏幕中添加图像视图:一种是通过在XML布局文件中使用<ImageView>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法。
在使用ImageView组件显示图像时,通常可以将要显示的图片放置在res/drawable目录中,然后应用下面的代码将其显示在布局管理器中。
- <ImageView
- 属性列表
- >
- </ImageView>
ImageView支持的常用XML属性如表3.6所示。
表3.6 ImageView支持的XML属性
XML属性 | 描 述 |
android:adjustViewBounds | 用于设置ImageView是否调整自己的边界来保持所显示图片的长宽比 |
android:maxHeight | 设置ImageView的最大高度,需要设置android:adjustViewBounds属性值为true,否则不起作用 |
android:maxWidth | 设置ImageView的最大宽度,需要设置android:adjustViewBounds属性值为true,否则不起作用 |
android:scaleType | 用于设置所显示的图片如何缩放或移动以适应ImageView的大小,其属性值可以是matrix(使用matrix方式进行缩放)、fitXY(对图片横向、纵向独立缩放,使得该图片完全适应于该ImageView,图片的纵横比可能会改变)、fitStart(保持纵横比缩放图片,直到该图片能完全显示在ImageView中,缩放完成后该图片放在ImageView的左上角)、fitCenter(保持纵横比缩放图片,直到该图片能完全显示在ImageView中,缩放完成后该图片放在ImageView的中央)、fitEnd(保持纵横比缩放图片,直到该图片能完全显示在ImageView中,缩放完成后该图片放在ImageView的右下角)、center(把图像放在ImageView的中间,但不进行任何缩放)、centerCrop(保持纵横比缩放图片,以使得图片能完全覆盖ImageView)或centerInside(保持纵横比缩放图片,以使得ImageView能完全显示该图片) |
android:src | 用于设置ImageView所显示的Drawable对象的ID,例如,设置显示保存在res/drawable目录下的名称为flower.jpg的图片,可以将属性值设置为android:src="@drawable/flower" |
android:tint | 用于为图片着色,其属性值可以是#rgb、#argb、#rrggbb或 #aarrggbb表示的颜色值 |
说明:在表3.6中,只给出了ImageView组件常用的部分属性,关于该组件的其他属性,可以参阅Android官方提供的API文档。
下面给出一个关于ImageView组件的实例。
例3.16 在Eclipse中创建Android项目,名称为3.16,应用ImageView组件显示图像。(实例位置:光盘\TM\sl\3\3.16)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的垂直线性布局管理器修改为水平线性布局管理器,并将默认添加的TextView组件删除,然后在该线性布局管理器中添加一个ImageView组件,用于按图片的原始尺寸显示图像,修改后的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/background"
- >
- <ImageView
- android:src="@drawable/flower"
- android:id="@+id/imageView1"
- android:layout_margin="5px"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- </LinearLayout>
(2)在线性布局管理器中,添加一个ImageView组件,并设置该组件的最大高度和宽度,具体代码如下:
- <ImageView
- android:src="@drawable/flower"
- android:id="@+id/imageView2"
- android:maxWidth="180px"
- android:maxHeight="180px"
- android:adjustViewBounds="true"
- android:layout_margin="5px"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
(3)添加一个ImageView组件,实现保持纵横比缩放图片,直到该图片能完全显示在ImageView组件中,并让该图片显示在ImageView组件的右下角,具体代码如下:
- <ImageView
- android:src="@drawable/flower"
- android:id="@+id/imageView3"
- android:scaleType="fitEnd"
- android:layout_margin="5px"
- android:layout_height="180px"
- android:layout_width="180px"/>
(4)添加一个ImageView组件,实现为显示在ImageView组件中的图像着色的功能,这里设置的是半透明的红色,具体代码如下:
- <ImageView
- android:src="@drawable/flower"
- android:id="@+id/imageView4"
- android:tint="#77ff0000"
- android:layout_height="180px"
- android:layout_width="180px"/>
运行本实例,将显示如图3.23所示的运行结果。
图3.23 应用ImageView显示图像
3.3.5 列表选择框
Android中提供的列表选择框(Spinner)相当于在网页中常见的下拉列表框,通常用于提供一系列可选择的列表项供用户进行选择,从而方便用户。
在Android中,可以使用两种方法向屏幕中添加列表选择框:一种是通过在XML布局文件中使用<Spinner>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法,也就是通过<Spinner>在XML布局文件中添加列表选择框,其基本语法格式如下:
- <Spinner
- android:prompt="@string/info"
- android:entries="@array/数组名称"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:id="@+id/ID号"
- >
- </Spinner>
其中,android:entries为可选属性,用于指定列表项,如果在布局文件中不指定该属性,可以在Java代码中通过为其指定适配器的方式指定;android:prompt属性也是可选属性,用于指定列表选择框的标题。
说明:在Android 4.0中,采用默认的主题(Theme.Holo)时,设置android:prompt属性看不到具体的效果,如果采用Theme.Black,就可以在弹出的下拉框中显示该标题。
通常情况下,如果列表选择框中要显示的列表项是可知的,那么可将其保存在数组资源文件中,然后通过数组资源来为列表选择框指定列表项。这样,就可以在不编写Java代码的情况下实现一个列表选择框。下面将通过一个具体的实例来说明如何在不编写Java代码的情况下,在屏幕中添加列表选择框。
例3.17 在Eclipse中创建Android项目,名称为3.17,实现在屏幕中添加列表选择框,并获取列表选择框的选择项的值。(实例位置:光盘\TM\sl\3\3.17)
(1)在布局文件中添加一个<spinner>标记,并为其指定android:entries属性,具体代码如下:
- <Spinner
- android:entries="@array/ctype"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:id="@+id/spinner1"/>
(2)编写用于指定列表项的数组资源文件,并将其保存在res\values目录中,这里将其命名为arrays.xml,在该文件中添加一个字符串数组,名称为ctype,具体代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string-array name="ctype">
- <item>身份证</item>
- <item>学生证</item>
- <item>军人证</item>
- <item>工作证</item>
- <item>其他</item>
- </string-array>
- </resources>
这样,就可以在屏幕中添加一个列表选择框,在模拟器中的运行结果如图3.24所示。
图3.24 在模拟器中显示的列表选择框
在屏幕上添加列表选择框后,可以使用列表选择框的getSelectedItem()方法获取列表选择框的选中值,例如,要获取图3.24所示列表选择框选中项的值,可以使用下面的代码:
- Spinner spinner = (Spinner) findViewById(R.id.spinner1);
- spinner.getSelectedItem();
添加列表选择框后,如果需要在用户选择不同的列表项后,执行相应的处理,则可以为该列表选择框添加OnItemSelectedListener事件监听器。例如,为spinner添加选择列表项事件监听器,并在onItemSelected()方法中获取选择项的值输出到日志中,可以使用下面的代码:
- //为选择列表框添加OnItemSelectedListener事件监听器
- spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView<?> parent, View arg1,
- int pos, long id) {
- String result = parent.getItemAtPosition(pos).toString(); //获取选择项的值
- Log.i("Spinner示例", result);
- }
- @Override
- public void onNothingSelected(AdapterView<?> arg0) {
- }
- });
在使用列表选择框时,如果不在布局文件中直接为其指定要显示的列表项,也可以通过为其指定适配器的方式指定。下面以例3.17为例介绍通过指定适配器的方式指定列表项的方法。
为列表选择框指定适配器,通常分为以下3个步骤实现。
(1)创建一个适配器对象,通常使用ArrayAdapter类。在Android中,创建适配器通常可以使用以下两种方法:一种是通过数组资源文件创建;另一种是通过在Java文件中使用字符串数组创建。
[√]通过数组资源文件创建
通过数组资源文件创建适配器,需要使用ArrayAdapter类的createFromResource()方法,具体代码如下:
- ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
- this, R.array.ctype,android.R.layout.simple_dropdown_item_1line); //创建一个适配器
[√]通过在Java文件中使用字符串数组创建
通过在Java文件中使用字符串数组创建适配器,首先需要创建一个一维的字符串数组,用于保存要显示的列表项,然后使用ArrayAdapter类的构造方法ArrayAdapter(Context context, int textViewResourceId, T[] objects)实例化一个ArrayAdapter类的实例,具体代码如下:
- String[] ctype=new String[]{"身份证","学生证","军人证"};
- ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,ctype);
(2)为适配器设置列表框下拉时的选项样式,具体代码如下:
- //为适配器设置列表框下拉时的选项样式
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
(3)将适配器与选择列表框关联,具体代码如下:
- spinner.setAdapter(adapter); //将适配器与选择列表框关联
3.3.6 列表视图
列表视图(ListView)是Android中最常用的一种视图组件,它以垂直列表的形式列出需要显示的列表项。例如,显示系统设置项或功能内容列表等。在Android中,可以使用两种方法向屏幕中添加列表视图:一种是直接使用ListView组件创建;另一种是让Activity继承ListActivity实现。下面分别进行介绍。
- 直接使用ListView组件创建
直接使用ListView组件创建列表视图,也可以有两种方式:一种是通过在XML布局文件中使用<ListView>标记添加;另一种是在Java文件中,通过new关键字创建。推荐采用第一种方法,也就是通过<ListView>在XML布局文件中添加ListView,其基本语法格式如下:
- <ListView
- 属性列表
- >
- </ListView>
ListView支持的常用XML属性如表3.7所示。
表3.7 ListView支持的XML属性
XML属性 | 描 述 |
android:divider | 用于为列表视图设置分隔条,既可以用颜色分隔,也可以用Drawable资源分隔 |
android:dividerHeight | 用于设置分隔条的高度 |
android:entries | 用于通过数组资源为ListView指定列表项 |
android:footerDividersEnabled | 用于设置是否在footer View之前绘制分隔条,默认值为true,设置为false时,表示不绘制。使用该属性时,需要通过ListView组件提供的addFooterView()方法为ListView设置footer View |
android:headerDividersEnabled | 用于设置是否在header View之后绘制分隔条,默认值为true,设置为false时,表示不绘制。使用该属性时,需要通过ListView组件提供的addHeaderView()方法为ListView设置header View |
例3.18 在布局文件中添加一个列表视图,并通过数组资源为其设置列表项。
具体代码如下:
- <ListView android:id="@+id/listView1"
- android:entries="@array/ctype"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"/>
在上面的代码中,使用了名称为ctype的数组资源,因此,需要在res\values目录中创建一个定义数组资源的XML文件arrays.xml,并在该文件中添加名称为ctype的字符串数组,关键代码如下:
- <resources>
- <string-array name="ctype">
- <item>情景模式</item>
- … <!-- 省略了其他项的代码 -->
- <item>连接功能</item>
- </string-array>
- </resources>
运行上面的代码,将显示如图3.25所示的列表视图。
图3.25 在布局文件中添加的列表视图
在使用列表视图时,重要的是如何设置选项内容。同Spinner列表选择框一样,如果没有在布局文件中为ListView指定要显示的列表项,也可以通过为其设置Adapter来指定需要显示的列表项。通过Adapter来为ListView指定要显示的列表项,可以分为以下两个步骤。
(1)创建Adapter对象。对于纯文字的列表项,通常使用ArrayAdapter对象。创建ArrayAdapter对象通常可以有两种方式:一种是通过数组资源文件创建;另一种是通过在Java文件中使用字符串数组创建。这与3.3.5节Spinner列表选择框中介绍的创建ArrayAdapter对象基本相同,所不同的就是在创建该对象时,指定列表项的外观形式。为ListView指定的外观形式通常有以下几个。
[√]simple_list_item_1:每个列表项都是一个普通的文本。
[√]simple_list_item_2:每个列表项都是一个普通的文本(字体略大)。
[√]simple_list_item_checked:每个列表项都有一个已选中的列表项。
[√]simple_list_item_multiple_choice:每个列表项都是带复选框的文本。
[√]simple_list_item_single_choice:每个列表项都是带单选按钮的文本。
(2)将创建的适配器对象与ListView相关联,可以通过ListView对象的setAdapter()方法实现,具体代码如下:
- listView.setAdapter(adapter); //将适配器与ListView关联
下面通过一个具体的实例演示通过适配器指定列表项来创建ListView。
例3.19 在Eclipse中创建Android项目,名称为3.19,实现在屏幕中添加列表视图,并为其设置footer view和header view。(实例位置:光盘\TM\sl\3\3.19)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的TextView组件删除,并添加一个ListView组件,添加ListView组件的布局代码如下:
- <ListView android:id="@+id/listView1"
- android:divider="@drawable/greendivider"
- android:dividerHeight="3px"
- android:footerDividersEnabled="false"
- android:headerDividersEnabled="false"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"/>
说明:在上面的代码中,为ListView组件设置了作为分隔符的图像以及分隔符的高度,另外,还设置了在footer view之前和header view之后不绘制分隔符。
(2)在主活动的onCreate()方法中为ListView组件创建并关联适配器。首先获取布局文件中添加的ListView,然后为其添加header view(需要注意的是,添加header view的代码必须在关联适配器的代码之前),再创建适配器,并将其与ListView相关联,最后为ListView组件添加footer view。关键代码如下:
- final ListView listView=(ListView)findViewById(R.id.listView1);
- listView.addHeaderView(line()); //设置header view
- /****************创建用于为ListView指定列表项的适配器********************/
- ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
- this, R.array.ctype,android.R.layout.simple_list_item_checked); //创建一个适配器
- /***************************************************************************/
- listView.setAdapter(adapter); //将适配器与ListView关联
- listView.addFooterView(line()); //设置footer view
(3)为了在单击ListView的各列表项时获取选择项的值,需要为ListView添加OnItemClickListener事件监听器,具体代码如下:
- listView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View arg1, int pos, long id) {
- String result = parent.getItemAtPosition(pos).toString(); //获取选择项的值
- Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show(); //显示提示消息框
- }
- });
运行本实例,将显示如图3.26所示的运行结果。
图3.26 应用ListView显示带头、脚视图的列表
- 让Activity继承ListActivity实现
如果程序的窗口仅仅需要显示一个列表,则可以直接让Activity继承ListActivity来实现。继承了ListActivity的类中无须调用setContentView()方法来显示页面,而是可以直接为其设置适配器,从而显示一个列表。下面通过一个实例来说明如何通过继承ListActivity实现列表。
例3.20 在Eclipse中创建Android项目,名称为3.20,通过在Activity中继承ListActivity实现列表。(实例位置:光盘\TM\sl\3\3.20)
(1)将新建项目中的主活动MainActivity修改为继承ListActivity的类,并将默认的设置用户布局的代码删除,然后在onCreate()方法中创建作为列表项的Adapter,并且使用setListAdapter()方法将其添加到列表中,关键代码如下:
- public class MainActivity extends ListActivity{
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- /****************创建用于为ListView指定列表项的适配器********************/
- String[] ctype=new String[]{"情景模式","主题模式","手机","程序管理"};
- ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,
- android.R.layout.simple_list_item_single_choice,ctype);
- /**********************************************************************************/
- setListAdapter(adapter); //设置该窗口中显示的列表
- }
- }
(2)为了在单击ListView的各列表项时获取选择项的值,需要重写父类中的onListItemClick()方法,具体代码如下:
- @Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
- super.onListItemClick(l, v, position, id);
- String result = l.getItemAtPosition(position).toString(); //获取选择项的值
- Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
- }
- }
运行本实例,将显示如图3.27所示的运行结果。
图3.27 通过继承ListActivity来实现列表视图
3.3.7 日期、时间拾取器
为了让用户能够选择日期和时间,Android提供了日期、时间拾取器,分别是DatePicker组件和TimePicker组件。这两个组件使用比较简单,可以在Eclipse的可视化界面设计器中,选择对应的组件并拖曳到布局文件中。为了可以在程序中获取用户选择的日期、时间,还需要为DatePicker和TimePicker组件添加事件监听器。其中,DatePicker组件对应的事件监听器是OnDateChangedListener,而TimePicker组件对应的事件监听器是OnTimeChangedListener。
下面通过一个具体的实例来说明日期、时间选择器的具体应用。
例3.21 在Eclipse中创建Android项目,名称为3.21,在屏幕中添加日期、时间拾取器,并实现在改变日期或时间时,通过消息提示框显示改变后的日期或时间。(实例位置:光盘\TM\sl\3\3.21)
(1)在新建项目的布局文件main.xml中,添加日期、时间拾取器,关键代码如下:
- <DatePicker android:id="@+id/datePicker1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <TimePicker android:id="@+id/timePicker1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
(2)在主活动MainActivity的onCreate()方法中,获取日期拾取组件和时间拾取组件,并将时间拾取组件设置为24小时制式显示,具体代码如下:
- DatePicker datepicker=(DatePicker)findViewById(R.id.datePicker1); //获取日期拾取组件
- TimePicker timepicker=(TimePicker)findViewById(R.id.timePicker1); //获取时间拾取组件
- timepicker.setIs24HourView(true);
(3)创建一个日历对象,并获取当前年、月、日、小时和分钟数,具体代码如下:
- Calendar calendar=Calendar.getInstance();
- year=calendar.get(Calendar.YEAR); //获取当前年份
- month=calendar.get(Calendar.MONTH); //获取当前月份
- day=calendar.get(Calendar.DAY_OF_MONTH); //获取当前日
- hour=calendar.get(Calendar.HOUR_OF_DAY); //获取当前小时数
- minute=calendar.get(Calendar.MINUTE); //获取当前分钟数
(4)初始化日期拾取组件,并在初始化时为其设置OnDateChangedListener事件监听器,以及为时间拾取组件添加事件监听器,具体代码如下:
- //初始化日期拾取器,并在初始化时指定监听器
- datepicker.init(year, month, day, new OnDateChangedListener(){
- @Override
- public void onDateChanged(DatePicker arg0,int year,int month,int day){
- MainActivity.this.year=year; //改变year属性的值
- MainActivity.this.month=month; //改变month属性的值
- MainActivity.this.day=day; //改变day属性的值
- show(year,month,day,hour,minute); //通过消息框显示日期和时间
- }
- });
- //为时间拾取器设置监听器
- timepicker.setOnTimeChangedListener(new OnTimeChangedListener() {
- @Override
- public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
- MainActivity.this.hour= hourOfDay; //改变hour属性的值
- MainActivity.this.minute=minute; //改变minute属性的值
- show(year,month,day, hourOfDay,minute); //通过消息框显示选择的日期和时间
- }
- });
(5)编写show()方法,用于通过消息框显示选择的日期和时间,具体代码如下:
- private void show(int year,int month,int day,int hour,int minute){
- String str=year+"年"+(month+1)+"月"+day+"日 "+hour+":"+minute; //获取拾取器设置的日期和时间
- Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); //显示消息提示框
- }
注意:由于通过DatePicker对象获取到的月份是0~11月,而不是1~12月,所以需要将获取的结果加1,才能代表真正的月份。
运行本实例,将显示如图3.28所示的运行结果。
图3.28 应用日期、时间拾取器选择日期和时间
3.3.8 计时器
计时器(Chronometer)组件可显示从某个起始时间开始,一共过去了多长时间的文本。由于该组件继承自TextView,所以它以文本的形式显示内容。使用该组件也比较简单,通常只需要使用以下5个方法。
[√]setBase():用于设置计时器的起始时间。
[√]setFormat():用于设置显示时间的格式。
[√]start():用于指定开始计时。
[√]stop():用于指定停止计时。
[√]setOnChronometerTickListener():用于为计时器绑定事件监听器,当计时器改变时触发该监听器。
下面通过一个具体的实例来说明计时器的应用。
例3.22 在Eclipse中创建Android项目,名称为3.22,在屏幕中添加一个“已用时间”计时器。(实例位置:光盘\TM\sl\3\3.22)
(1)在新建项目的布局文件main.xml中,添加id属性为chronometer1的计时器组件,关键代码如下:
- <Chronometer
- android:text="Chronometer"
- android:id="@+id/chronometer1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
(2)在主活动MainActivity的onCreate()方法中获取计时器组件,并设置起始时间和显示时间的格式、开启计时器,以及为其添加监听器,具体代码如下:
- final Chronometer ch = (Chronometer) findViewById(R.id.chronometer1); //获取计时器组件
- ch.setBase(SystemClock.elapsedRealtime()); //设置起始时间
- ch.setFormat("已用时间:%s"); //设置显示时间的格式
- ch.start(); //开启计时器
- //添加监听器
- ch.setOnChronometerTickListener(new OnChronometerTickListener() {
- @Override
- public void onChronometerTick(Chronometer chronometer) {
- if (SystemClock.elapsedRealtime() - ch.getBase() >= 10000) {
- ch.stop(); //停止计时器
- }
- }
- });
运行本实例,将显示如图3.29所示的运行结果。
图3.29 显示计时器
3.3.9 范例1:实现跟踪鼠标单击状态的图片按钮
例3.23 在Eclipse中创建Android项目,名称为3.23,实现跟踪鼠标单击状态的图片按钮。(实例位置:光盘\TM\sl\3\3.23)
(1)修改新建项目的res\layout目录下的布局文件main.xml,为默认添加的垂直线性布局添加背景,并设置该布局中的内容居中显示,然后添加一个ImageButton图片按钮,并将其设置为透明背景。修改后的代码如下:
- <?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"
- android:background="@drawable/background"
- android:gravity="center"
- >
- <ImageButton
- android:id="@+id/start"
- android:background="#0000"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- </ImageButton>
- </LinearLayout>
说明:在默认情况下,为图片按钮设置android:src后,该图片按钮将带一个灰色的背景,不是很美观,为了去除灰色的背景,可以将其背景设置为透明(上面代码中将背景设置为#0000,即黑色透明),不过这样该图片按钮将不再有鼠标单击效果。
(2)编写Drawable资源对应的XML文件button_state.xml,用于设置当鼠标按下时显示的图片和鼠标没有按下时显示的图片,具体代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <selector
- xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/start_b"/>
- <item android:state_pressed="false" android:drawable="@drawable/start_a"/>
- </selector>
(3)为main.xml布局文件中的图片按钮设置android:src属性,其属性值是在步骤(2)中编写的Drawable资源,关键代码如下:
- android:src="@drawable/button_state"
(4)在主活动的onCreate()方法中,获取布局文件中添加的图片按钮,并为其添加鼠标单击事件监听器,具体代码如下:
- ImageButton imageButton=(ImageButton)findViewById(R.id.start); //获取“进入”按钮
- //为按钮添加单击事件监听器
- imageButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Toast.makeText(MainActivity.this, "进入游戏...", Toast.LENGTH_SHORT).show(); //显示消息提示框
- }
- });
运行本实例,将显示如图3.30所示的运行结果,单击“进入”按钮,当单击鼠标时,按钮将变成橙色背景。
图3.30 跟踪鼠标单击状态的图片按钮
3.3.10 范例2:实现带图标的ListView
例3.24 在Eclipse中创建Android项目,名称为3.24,实现带图标的ListView。(实例位置:光盘\TM\sl\3\3.24)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的TextView组件删除,然后添加一个id属性为listView1的ListView组件。修改后的代码如下:
- <ListView
- android:id="@+id/listView1"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"/>
(2)编写用于布局列表项内容的XML布局文件items.xml,在该文件中,采用水平线性布局管理器,并在该布局管理器中添加一个ImageView组件和一个TextView组件,分别用于显示列表项中的图标和文字,具体代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ImageView
- android:id="@+id/image"
- android:paddingRight="10px"
- android:paddingTop="20px"
- android:paddingBottom="20px"
- android:adjustViewBounds="true"
- android:maxWidth="72px"
- android:maxHeight="72px"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="10px"
- android:layout_gravity="center"
- android:id="@+id/title"
- />
- </LinearLayout>
(3)在主活动的onCreate()方法中,首先获取布局文件中添加的ListView,然后创建两个用于保存列表项图片id和文字的数组,并将这些图片id和文字添加到List集合中,再创建一个SimpleAdapter简单适配器,最后将该适配器与ListView相关联,具体代码如下:
- ListView listview = (ListView) findViewById(R.id.listView1); //获取列表视图
- int[] imageId = new int[] { R.drawable.img01, R.drawable.img02, R.drawable.img03,
- R.drawable.img04, R.drawable.img05, R.drawable.img06,
- R.drawable.img07, R.drawable.img08 }; //定义并初始化保存图片id的数组
- String[] title = new String[] { "保密设置", "安全", "系统设置", "上网", "我的文档",
- "GPS导航", "我的音乐", "E-mail" }; //定义并初始化保存列表项文字的数组
- List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>(); //创建一个List集合
- //通过for循环将图片id和列表项文字放到Map中,并添加到List集合中
- for (int i = 0; i < imageId.length; i++) {
- Map<String, Object> map = new HashMap<String, Object>(); //实例化map对象
- map.put("image", imageId[i]);
- map.put("title", title[i]);
- listItems.add(map); //将map对象添加到List集合中
- }
- SimpleAdapter adapter = new SimpleAdapter(this, listItems,
- R.layout.items, new String[] { "title", "image" }, new int[] {
- R.id.title, R.id.image }); //创建SimpleAdapter
- listview.setAdapter(adapter); //将适配器与ListView关联
说明:SimpleAdapter类的构造方法SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)中,参数context用于指定关联SimpleAdapter运行的视图上下文;参数data用于指定一个基于Map的列表,该列表中的每个条目对应列表中的一行;参数resource用于指定一个用于定义列表项目的视图布局文件的唯一标识;参数from用于指定一个将被添加到Map上关联每一个项目的列名称的数组;参数to用于指定一个与参数from显示列对应的视图id的数组。
运行本实例,将显示如图3.31所示的运行结果。
图3.31 带图标的ListView
3.4 经典范例
3.4.1 我同意游戏条款
例3.25 在Eclipse中创建Android项目,名称为3.25,实现游戏开始界面中的我同意游戏条款功能。(实例位置:光盘\TM\sl\3\3.25)
(1)修改新建项目的res\layout目录下的布局文件main.xml,为默认添加的垂直线性布局管理器添加背景,并设置该布局管理器中的内容居中显示,然后添加一个用于显示游戏条款的TextView组件、一个“我同意”复选框和一个ImageButton图片按钮,并设置图片按钮默认为不显示以及透明背景。修改后的代码如下:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@drawable/background"
- android:gravity="center" >
- <!-- 显示游戏条款的TextView -->
- <TextView
- android:text="@string/artcle"
- android:id="@+id/textView1"
- android:paddingTop="120px"
- style="@style/artclestyle"
- android:maxWidth="700px"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <!-- “我同意”复选框 -->
- <CheckBox
- android:text="我同意"
- android:id="@+id/checkBox1"
- android:textSize="22px"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <!-- 图片按钮 -->
- <ImageButton
- android:id="@+id/start"
- android:background="#0000"
- android:paddingTop="30px"
- android:visibility="invisible"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- </ImageButton>
- </LinearLayout>
(2)由于复选框默认的效果显示到本实例的绿色背景上时,看不到前面的方块,所以需要改变复选框的默认效果。首先编写Drawable资源对应的XML文件check_box.xml,用于设置复选框没有被选中时显示的图片以及被选中时显示的图片,具体代码如下:
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="false"
- android:drawable="@drawable/check_f"/>
- <item android:state_checked="true"
- android:drawable="@drawable/check_t"/>
- </selector>
(3)为main.xml布局文件中的复选框设置android:button属性,其属性值是在步骤(2)中编写的Drawable资源,关键代码如下:
- android:button="@drawable/check_box"
(4)由于ImageButton组件设置背景透明后,将不再显示鼠标单击效果,所以需要通过Drawable资源来设置图片的android:src属性。首先编写一个Drawable资源对应的XML文件button_state.xml,用于设置当鼠标按下时显示的图片以及鼠标没有按下时显示的图片,具体代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <selector
- xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/start_b"/>
- <item android:state_pressed="false" android:drawable="@drawable/start_a"/>
- </selector>
(5)为main.xml布局文件中的图片按钮设置android:src属性,其属性值是在步骤(4)中编写的Drawable资源,关键代码如下:
- android:src="@drawable/button_state"
(6)在res/values目录下的strings.xml文件中,添加字符串变量artcle,用于保存游戏条款,关键代码如下:
- <string name="artcle">         温馨提示:本游戏适合各年龄段的玩家,请您合理安排游戏时间,不要沉迷游戏!
- 当您连续在线2小时间后,系统将自动结束游戏。如果同意该条款请勾选“我同意”复选框,方可进入游戏。
- </string>
说明:在Android中,空格使用“ ”表示。
(7)在主活动的onCreate()方法中,获取布局文件中添加的“进入”图片按钮和“我同意”复选框,并为复选框添加状态改变监听器,用于实现当复选框被选中时显示“进入”按钮,否则不显示。具体代码如下:
- final ImageButton imageButton=(ImageButton)findViewById(R.id.start); //获取“进入”按钮
- CheckBox checkbox=(CheckBox)findViewById(R.id.checkBox1); //获取布局文件中添加的复选框
- //为复选框添加监听器
- checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if(isChecked){ //当复选框被选中时
- imageButton.setVisibility(View.VISIBLE); //设置“进入”按钮显示
- }else{
- imageButton.setVisibility(View.INVISIBLE); //设置“进入”按钮不显示
- }
- imageButton.invalidate(); //重绘ImageButton
- }
- });
(8)为“进入”按钮添加单击事件监听器,用于实现当用户单击该按钮时,显示一个消息提示框,具体代码如下:
- imageButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //显示消息提示框
- Toast.makeText(MainActivity.this, "进入游戏...", Toast.LENGTH_SHORT).show();
- }
- });
运行本实例,将显示如图3.32所示的运行结果。
图3.32 我同意游戏条款的效果
3.4.2 猜猜鸡蛋放在哪只鞋子里
例3.26 在Eclipse中创建Android项目,名称为3.26,实现猜猜鸡蛋放在哪只鞋子里的小游戏。(实例位置:光盘\TM\sl\3\3.26)
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的垂直线性布局管理器的代码删除,然后添加一个带有3个表格行的TableView布局管理器,其中第1行中添加一个TextView组件,用于显示游戏标题或提示信息;第2行添加一个包含3个ImageView组件的水平线性布局管理器;最后一行添加一个水平线性布局管理器,并且在其中添加一个“再玩一次”按钮。修改后的代码如下:
- <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:background="@drawable/background"
- android:id="@+id/tableLayout1">
- <TableRow android:id="@+id/tableRow1"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:gravity="center"
- android:layout_weight="2">
- <TextView
- android:text="@string/title"
- android:padding="10px"
- android:gravity="center"
- android:textSize="35px"
- android:textColor="#010D18"
- android:id="@+id/textView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- </TableRow>
- <TableRow
- android:id="@+id/tableRow2"
- android:layout_weight="1"
- android:gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
- <ImageView android:id="@+id/imageView1"
- android:src="@drawable/shoe_default"
- android:paddingLeft="30px"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- … <!-- 此处省略其他两个ImageView组件的代码,这两个组件的id属性分别是imageView2和 imageView3 -->
- </LinearLayout>
- </TableRow>
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:layout_weight="1"
- android:gravity="center_horizontal">
- <Button
- android:text="再玩一次"
- android:id="@+id/button1"
- android:layout_width="wrap_content" android:layout_height="wrap_content"/>
- </LinearLayout>
- </TableLayout>
(2)在主活动MainActivity中,定义一个保存全部图片id的数组、3个ImageView类型的对象和一个TextView类型的对象,具体代码如下:
- int[] imageIds = new int[] { R.drawable.shoe_ok, R.drawable.shoe_sorry,
- R.drawable.shoe_sorry }; //定义一个保存全部图片id的数组
- private ImageView image1; //ImageView组件1
- private ImageView image2; //ImageView组件2
- private ImageView image3; //ImageView组件3
- private TextView result; //显示结果
(3)编写一个无返回值的方法reset(),用于随机指定鸡蛋所在的鞋子,关键代码如下:
- private void reset() {
- for (int i = 0; i < 3; i++) {
- int temp = imageIds[i]; //将数组元素i保存到临时变量中
- int index = (int) (Math.random() * 2); //生成一个随机数
- imageIds[i] = imageIds[index]; //将随机数指定的数组元素的内容赋值给数组元素i
- imageIds[index] = temp; //将临时变量的值赋值给随机数组指定的数组元素
- }
- }
(4)由于ImageButton组件设置背景透明后,将不再显示鼠标单击效果,所以需要通过Drawable资源来设置图片的android:src属性。首先编写一个Drawable资源对应的XML文件button_state.xml,用于设置当鼠标按下时显示的图片以及鼠标没有按下时显示的图片,具体代码如下:
- image1 = (ImageView) findViewById(R.id.imageView1); //获取ImageView1组件
- image2 = (ImageView) findViewById(R.id.imageView2); //获取ImageView2组件
- image3 = (ImageView) findViewById(R.id.imageView3); //获取ImageView3组件
- result = (TextView) findViewById(R.id.textView1); //获取TextView组件
- reset(); //将鞋子的顺序打乱
(5)为3个显示鞋子的ImageView组件添加单击事件监听器,用于将鞋子打开,并显示猜猜看的结果,关键代码如下:
- //为第1只鞋子添加单击事件监听器
- image1.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- isRight(v, 0); //判断结果
- }
- });
- //为第2只鞋子添加单击事件监听器
- image2.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- isRight(v, 1); //判断结果
- }
- });
- //为第3只鞋子添加单击事件监听器
- image3.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- isRight(v, 2); //判断结果
- }
- });
(6)编写isRight()方法,用于显示打开的鞋子,并显示判断结果,具体代码如下:
- /**
- * 判断猜出的结果
- *
- * @param v
- * @param index
- */
- private void isRight(View v, int index) {
- //使用随机数组中图片资源ID设置每个ImageView
- image1.setImageDrawable(getResources().getDrawable(imageIds[0]));
- image2.setImageDrawable(getResources().getDrawable(imageIds[1]));
- image3.setImageDrawable(getResources().getDrawable(imageIds[2]));
- //为每个ImageView设置半透明效果
- image1.setAlpha(100);
- image2.setAlpha(100);
- image3.setAlpha(100);
- ImageView v1 = (ImageView) v; //获取被单击的图像视图
- v1.setAlpha(255); //设置图像视图的透明度
- if (imageIds[index] == R.drawable.shoe_ok) { //判断是否猜对
- result.setText("恭喜您,猜对了,祝你幸福!");
- } else {
- result.setText("很抱歉,猜错了,要不要再试一次?");
- }
- }
(7)获取“再玩一次”按钮,并为该按钮添加单击事件监听器,在其单击事件中,首先将标题恢复为默认值,然后设置3个ImageView的透明度为完全不透明,最后设置这3个ImageView的图像内容为默认显示图片,具体代码如下:
- Button button = (Button) findViewById(R.id.button1); //获取“再玩一次”按钮
- //为“再玩一次”按钮添加事件监听器
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- reset();
- result.setText(R.string.title); //将标题恢复为默认值
- image1.setAlpha(255);
- image2.setAlpha(255);
- image3.setAlpha(255);
- image1.setImageDrawable(getResources().getDrawable( R.drawable.shoe_default));
- image2.setImageDrawable(getResources().getDrawable(R.drawable.shoe_default));
- image3.setImageDrawable(getResources().getDrawable(R.drawable.shoe_default));
- }
- });
运行本实例,将显示如图3.33所示的运行结果,单击其中的任意一只鞋子,将打开鞋子,显示里面是否有鸡蛋,并且将没有被单击的鞋子设置为半透明显示,被单击的鞋子正常显示,同时根据单击的鞋子里是否有鸡蛋显示对应的结果。例如,单击中间的鞋子,如果鸡蛋在这只鞋子里,将显示如图3.34所示的运行结果;否则,将显示“很抱歉,猜错了,要不要再试一次?”的提示文字。
![]() | ![]() |
图3.33 默认的运行结果 | 图3.34 单击中间鞋子显示的运行结果 |
3.5 小 结
本章介绍了进行用户界面设计的基础内容,主要包括Android中控制UI界面的4种方法、常用的4种布局管理器和一些常用的基本组件。首先介绍的是控制UI界面的4种方法,这4种方法各有优缺点,应根据实际需要选择最为合适的方法,然后介绍线性布局、表格布局、帧布局和相对布局4种布局方式,需要读者重点掌握,在实际编程中经常使用,接下来又介绍了常用的基本组件,最后结合前面介绍的内容给出了两个经典范例,用于巩固所学的知识。
3.6 实践与练习
编写Android程序,实现通过ImageView显示带边框的图片。(答案位置:光盘\TM\sl\3\3.27)
编写Android程序,实现选中复选框后,“开始”按钮才可用,否则为不可用状态。(答案位置:光盘\TM\sl\3\3.28)
编写Android程序,实现图标在上、文字在下的ListView。(答案位置:光盘\TM\sl\3\3.29)