引言:
一个好的应用界面的必备条件是:内容清楚、指示明白、屏幕美观和有亲切感。界面通常包含图形和文字。应用界面的设计是对控件进行适当的取舍及功能的选择和处理的过程。在程序设计中,需要对设计的方法反复推敲、琢磨,才能使其达到完美。
Android应用程序的基础功能淡单元就是Activity类中的一个对象。Activity可以做很多事,比如界面显示、事件处理等。Android应用程序的界面通常使用View和ViewGroup控件配XML样式来进行设计。而事件则包含按钮点击事件、触屏事件以及一些高级控件的事件监听。下面我们分别介绍Activit的界面设计、显示和事件处理。
用户界面简介:
Android生成屏幕有三种方式:XML配置生成、通过用户界面接口生成、直接用代码生成。在一个Android应用中,用户界面是由View和ViewGroup对象构成。View和ViewGroup都有很多种类,而它们都是View类的子类。开发人员可以对View和ViewGroup进行组合,来完成应用程序的界面设计。
4.1.1 VIew
任何一个View对象都继承android.view.View类。它是一个存储有屏幕上特定的一个矩形布局和内容属性的数据结构。一个View对象可以处理测距、布局、绘图、焦点变换、滚动条,以及屏幕区域自己表现的按键和手势。作为一个基类,VIew类为Widget服务,Widget则是一组用于绘制交互屏幕元素的完全实现子类。Widget处理自己的测距和绘图,所以可以快速的用他们去构建UI。可以使用到Widget包含Text、EditText、Button、RadioButton、Checkbox和ScrollView等。
4.1.2 VIewGroup
ViewGroup是一个特殊的View,可以包含其他视图(称为子视图)。而ViewGroup是View的子类,所以ViewGroup可以当成普通的UI组件使用。ViewGroup是布局和视图容器的基类,该类还定义了ViewGroup.LayoutParams用作布局参数基类的类。
由于ViewGroup的直接子类和间接子类比较多,上图描述了展示了部分子类。
4.2 事件处理
什么是事件呢?事件就是用户与UI(界面)交互时所触发的操作。例如,在手机键盘上按下一个键,就可以触发几个事件。键盘上的键被按下时就会触发了“按下”事件,当松开按键时又会触发“弹起”事件。在Android中,这些事件都将被传送到事件处理器,它是一个专门接受事件对象并对其进行翻译和处理的方法。
在Java程序中,实现与用户的交互功能的控件都需要通过事件来处理,需要指定控件所用的事件监听器。当然,Android同样需要设置事件监听器。另外,在Android下,View同样可以响应按键和触屏两种事件,分别如下所示:
类型 | 方法 | 说明 |
boolean | onKeyDown(int keyCode, KeyEvent event) | 用于响应按键按下 |
boolean | onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) | 用于响应按键重复点击,官方API指出onKeyMultiple方法总是返回false,即它没有handle,因此必须重写才能实现。 |
boolean | onKeyUp(int keyCode, KeyEvent event) | 用于响应按键释放 |
boolean | onTouchEvent(MotionEvent event) | 用于响应触摸屏事件 |
我们通过示例来处理各种事件,主要包含:Button控件事件监听、按键按下事件、按键弹出事件、触屏点击事件。
public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityEventSource {
public boolean onTouchEvent(MotionEvent event) {
public boolean onTrackballEvent(MotionEvent event) {
protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
}
相关方法的说明:
Android提供了以下回调方法供用户使用:
4.2.1. onKeyDown:
功能:该方法是接口KeyEvent.Callback中的抽象方法,所有的View全部实现了该接口并重写了该方法,该方法用来捕捉手机键盘被按下的事件。
声明:public boolean onKeyDown (int keyCode, KeyEvent event)
参数说明:
参数keyCode,该参数为被按下的键值即键盘码,手机键盘中每个按钮都会有其单独的键盘码,在应用程序都是通过键盘码才知道用户按下的是哪个键。
参数event,该参数为按键事件的对象,其中包含了触发事件的详细信息,例如事件的状态、事件的类型、事件发生的时间等。当用户按下按键时,系统会自动将事件封 装成KeyEvent对象供应用程序使用。
返回值,该方法的返回值为一个boolean类型的变量,当返回true时,表示已经完整地处理了这个事件,并不希望其他的回调方法再次进行处理,而当返回false时,表示并没有完全处理完该事件,更希望其他回调方法继续对其进行处理,例如Activity中的回调方法。
4.2.2. onKeyUp:
功能:该方法同样是接口KeyEvent.Callback中的一个抽象方法,并且所有的View同样全部实现了该接口并重写了该方法,onKeyUp方法用来捕捉手机键盘按键抬起的事件。
声明:public boolean onKeyUp (int keyCode, KeyEvent event)
参数说明: 同onKeyDown
4.2.3. onTouchEvent:
功能:该方法在View类中的定义,并且所有的View子类全部重写了该方法,应用程序可以通过该方法处理手机屏幕的触摸事件。
声明:public boolean onTouchEvent (MotionEvent event)
说明:
参数event:参数event为手机屏幕触摸事件封装类的对象,其中封装了该事件的所有信息,例如触摸的位置、触摸的类型以及触摸的时间等。该对象会在用户触摸手机屏幕时被创建。
返回值:该方法的返回值机理与键盘响应事件的相同,同样是当已经完整地处理了该事件且不希望其他回调方法再次处理时返回true,否则返回 false。
详细说明:该方法并不像之前介绍过的方法只处理一种事件,一般情况下以下三种情况的事件全部由onTouchEvent方法处理,只是三种情况中的动作值不同。
屏幕被按下:当屏幕被按下时,会自动调用该方法来处理事件,此时MotionEvent.getAction()的值为 MotionEvent.ACTION_DOWN,如果在应用程序中需要处理屏幕被按下的事件,只需重新该回调方法,然后在方法中进行动作的判断即可。
屏幕被抬起:当触控笔离开屏幕时触发的事件,该事件同样需要onTouchEvent方法来捕捉,然后在方法中进行动作判断。当 MotionEvent.getAction()的值为MotionEvent.ACTION_UP时,表示是屏幕被抬起的事件。
在屏幕中拖动:该方法还负责处理触控笔在屏幕上滑动的事件,同样是调用MotionEvent.getAction()方法来判断动作值是否为 MotionEvent.ACTION_MOVE再进行处理。
4.2.4.onTrackBallEvent:
功能: 接下来将介绍的是手机中轨迹球的处理方法onTrackBallEvent。所有的View同样全部实现了该方法。
声明: public boolean onTrackballEvent (MotionEvent event)
详细说明:该方法的使用方法与前面介绍过的各个回调方法基本相同,可以在Activity中重写该方法,也可以在各个View的实现类中重写。
参数event:参数event为手机轨迹球事件封装类的对象,其中封装了触发事件的详细信息,同样包括事件的类型、触发时间等,一般情况下,该对象会在用户操控轨迹球时被创建。
返回值:该方法的返回值与前面介绍的各个回调方法的返回值机制完全相同,因本书篇幅有限,不再赘述。
轨迹球与手机键盘的区别如下所示:
1).某些型号的手机设计出的轨迹球会比只有手机键盘时更美观,可增添用户对手机的整体印象。
2).轨迹球使用更为简单,例如在某些游戏中使用轨迹球控制会更为合理。
3).使用轨迹球会比键盘更为细化,即滚动轨迹球时,后台的表示状态的数值会变化得更细微、更精准。
提示:在模拟器运行状态下,可以通过F6键打开模拟器的轨迹球,然后便可以通过鼠标的移动来模拟轨迹球事件。
4.2.5.onFocusChanged:
功能:前面介绍的各个方法都可以在View及Activity中重写,接下来介绍的onFocusChanged却只能在View中重写。该方法是焦点改变的回调方法,当某个控件重写了该方法后,当焦点发生变化时,会自动调用该方法来处理焦点改变的事件。
声明:
protected void onFocusChanged (boolean gainFocus, int direction, Rect previously FocusedRect)
详细说明:
(1).参数gainFocus:参数gainFocus表示触发该事件的View是否获得了焦点,当该控件获得焦点时,gainFocus等于true,否则等于false。
(2).参数direction:参数direction表示焦点移动的方向,用数值表示,有兴趣的读者可以重写View中的该方法打印该参数进行观察。
(3).参数previouslyFocusedRect:表示在触发事件的View的坐标系中,前一个获得焦点的矩形区域,即表示焦点是从哪里来的。如果不可用则为null。
焦点:焦点描述了按键事件(或者是屏幕事件等)的承受者,每次按键事件都发生在拥有焦点的View上。在应用程序中,我们可以对焦点进行控制,例如从一个 View移动另一个View。
下面列出一些与焦点有关的常用方法:
方法名称 | 说明 |
setFocusable | 设置View是否可以拥有焦点 |
isFocusable | 监测此View是否可以拥有焦点 |
setNextFocusDownId | 设置View的焦点向下移动后获得焦点View的ID |
hasFocus | 返回了View的父控件是否获得了焦点 |
requestFocus | 尝试让此View获得焦点 |
isFocusableTouchMode | 设置View是否可以在触摸模式下获得焦点,在默认情况下是不可用获得的 |