Android学习笔记--处理UI事件
Handling UI Events
在Android里, 有不只一种方式可以截获用户与你的应用程序交互的事件. 在你的界面上处理事件时,你需要捕获用户与某个View实例交互时所产生的事件.View类支持这种做法.
在
你布局时需要使用的很多View类型里,你应该注意到一些对处理UI事件很有用的公有回调方法. 当特定操作发生在一些指定对象的时候,Android系
统的frmaework程序就会调用这些回调方法. 比如,当我们touch某个按钮的时候,它的onTouchEvent()方法就会被调用. 但是,
为了拦截这一过程,你必须继承某个类并且重写它的onTouchEvent()方法. 显然,这样处理所有View对象上触发的事件是不切实际的.这就是
为什么View类也包含了一组嵌套接口,它允许我们更加容易的定义自己想要的行为. 这些接口,叫做事件监听器,是你捕获用户与应用程序界面交互的关键所
在.
在你总是使用事件监听器来监听用户行为的同时,哪一天你可能确实需要继承某一个View类以建立一个自定义组件.这种情况下,你可以使用类里所定义的事件处理器来为你的类定义默认的事件处理行为.
1.事件监听器
一个事件监听器就是View类里一个包含单个回调方法的接口. 事件监听器需要被注册到某个View上,当用户在界面上的操作触发这个事件时,Android系统的frmaework程序就会调用这个监听里的回调方法.
包含在事件监听器接口的回调方法有以下这些:
(1)onClick()----来自于 View.OnClickListener
当用户touch the item (when in touch mode), 使用导航键将焦点置于此项并按下ENTER键 ,或者使用trackball选中此项并按下trackball时,这个方法会被调用.
(2)onLongClick()----来自于 View.OnLongClickListener
This
is called when the user either touches and holds the item (when in
touch mode), or focuses upon the item with the navigation-keys or
trackball and presses and holds the suitable "enter" key or presses and
holds down on the trackball (for one second).
(3)onFocusChange()----View.OnFocusChangeListener
当用户使用navigation-key或者trackball,将焦点切换到或者离开某个选项时,这个方法被调用.
(4)onKey()----来自于 View.OnKeyListener.
当用户在焦点项上,按下或者释放设备上某个键时,这个方法会被调用.
(5)onTouch()----来自于 View.OnTouchListener
This
is called when the user performs an action qualified as a touch event,
including a press, a release, or any movement gesture on the screen
(within the bounds of the item).
参阅android.view.MotionEvent类的ACTION_CANCEL,ACTION_DOWN,ACTION_MOVE,ACTION_UP等字段.
(6)onCreateContextMenu()----来自于 View.OnCreateContextMenuListener.
当创建一个Context Menu的时候,这个方法会被调用.参阅Creating Menus文档的context menu部分.
上
述这些方法是它们各自接口的唯一内容.为了定义它们中的任何一个来处理你的事件,需要使你的Activity实现某个接口,或者在某个匿名内部类里定义接
口的默认行为.然后,传递你的实现方式的一个实例到相应的View.set...Listener()方法里去.下面是创建一个匿名实现类的例子代码段:
// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
public void onClick(View v) {
// do something when the button is clicked
}
};
protected void onCreate(Bundle savedValues) {
...
// Capture our button from layout
Button button = (Button)findViewById(R.id.corky);
// Register the onClick listener with the implementation above
button.setOnClickListener(mCorkyListener);
...
}
当然还有另一种更方便的选择,那就是把实现On...Listener作为你的Activity的一部分来做. 好处是可以避免额外的类载入和对象分配.示例代码如下:
public class ExampleActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedValues) {
...
Button button = (Button)findViewById(R.id.corky);
button.setOnClickListener(this);
}
// Implement the OnClickListener callback
public void onClick(View v) {
// do something when the button is clicked
}
...
}
注意:上面例子中的onClick()方法没有返回值,但是有一些事件监听器方法必须返回一个布尔值.这是根据事件本身而定的,我们来看看几个有返回值的方法.
(1)onLongClick()方法.
它的返回值指示了你是否完成了事件处理工作并且要求事件就此终止而不再继续向下传递.也就是说,返回true说明你已经处理了这个事件并且它应该就此终止;
返回false则说明你没有处理事件,或者这个事件应该继续被传递到其它的某个监听上.
(2)onKey()方法.
同上.
(3)onTouch()方法.
同
样的,它的返回值指示你的listener是否处理了此事件.重要的是,这一事件可以有多个行为,互相追随(参阅
android.view.MotionEvent类的
ACTION_CANCEL,ACTION_DOWN,ACTION_MOVE,ACTION_UP等)。所以,如果你在down行为的处理中返回了
false,表明你还没有处理事件并且对此事件里的其它行为也不感兴趣.因此,你也不会收到此事件里其它任何行为的通知,比如用户做的一个fingure
手势或者最终的up行为时.
要记住,关键事件总是被分发到当前的焦点View.它们被派从顶部的View层次,然后下来,直到它们达到适当
的终点。如果焦点在你的View(或者你的View的子元素)上,你可以看见被触发的事件经过dispatchKeyEvent()方法.对于捕获经过你
的View的关键事件,还有一个替代方案,就是在你的Activity里使用onKeyDown() 和 onKeyUp()方法.
注
意:Android会首先调用事件处理器(View.on...Listener),然后才会从类里寻找合适的事件处理定义
(View.onKeyDown等等[Activity.onKeyDown?????]).同样的,从事件监听器里返回true将会打断到其它监听器的
传播,并且会阻塞View里默认事件处理器的回调.所以,当你从事件监听器里返回true的时候,一定要小心,确认自己真的想要终止事件的处理和传播.
2.事件处理程序
如果你正在使用View类创建自定义组件,你可以定义几个回调方法作为默认的事件处理程序.在"Building Custom Components"的文档里,可以学习到使用一些回调方法来处理事件,包括:
* onKeyDown(int, KeyEvent) - Called when a new key event occurs.
* onKeyUp(int, KeyEvent) - Called when a key up event occurs.
* onTrackballEvent(MotionEvent) - Called when a trackball motion event occurs.
* onTouchEvent(MotionEvent) - Called when a touch screen motion event occurs.
* onFocusChanged(boolean, int, Rect) - Called when the view gains or loses focus.
还有一些我们应该注意的方法, 它们不属于View类, 却影响到我们处理事件的方式.因此,在布局内部处理复杂的事件时,请考虑到它们:
* Activity.dispatchTouchEvent(MotionEvent) - This allows your Activity
to intercept all touch events before they are dispatched to the window.
* ViewGroup.onInterceptTouchEvent(MotionEvent) - This allows a
ViewGroup to watch events as they are dispatched to child Views.
* ViewParent.requestDisallowInterceptTouchEvent(boolean) - Call this
upon a parent View to indicate that it should not intercept touch events
with onInterceptTouchEvent(MotionEvent).
3.触摸模式
当
用户正通过方向键或者trackball浏览界面时,我们需要把焦点设置到那些可操作的item上面,以使用户明白哪里处理它的请求. 但是,如果某个设
备具备触摸响应能力,用户会直接通过触摸来与应用程序交互,不再需要我们高亮显示某个item或者为某个view设置焦点了. 所以,我们称这种交互模式
为触摸模式.
对于一个有触摸功能的设备来说,一旦用户触摸了屏幕,此设备立即进入触摸模式. 从这点开始,只有那些
isFocusableInTouchMode()为true的View可以设置焦点,比如文本编辑widget.其它那些可触摸的View,比如按钮,
被触摸时也不会获得焦点;它们只是在自己被pressed的时候简单地激活on-click监听器.
任何时候,一个用户点击一个方向键或用轨迹球滚动,该设备将退出触摸模式,并把焦点设置到某个View上.现在,用户可以恢复与没有触摸屏的用户界面交互。
触摸模式的状态保持在整个系统(所有窗口和活动)。要查询当前的状态,你可以调用isInTouchMode(),看看是否该设备目前在触摸模式。
4.处理焦点
该
框架将处理响应用户输入过程中的例行焦点移动.包括在View被删除或者隐藏`
新建View时改变焦点.Views通过isFocusable()方法表达它们获取焦点的意愿.如果要改变某个View能否接受焦点,调用
setFocusable()方法.在触摸模式下,你可以使用isFocusableInTouchMode()方法查询某个View是否被允许设置为焦
点.同样地,也有办法改变这个属性,调用setFocusableInTouchMode()方法就行.
确定下一个焦点的算法是寻找指定方
向上的最近相邻元素. 很少见的时候, 默认算法的结果不符合开发人员的预期行为,这种情况下,可以通过下面几个XML属性明确指定焦点移动的结
果:nextFocusDown, nextFocusLeft, nextFocusRight, and
nextFocusUp. 添加这些属性中的一个到焦点将要离开的View定义里.把你想要下
一个focus的View的ID设置为相应属性的值.比如:
<LinearLayout
android:orientation="vertical"
... >
<Button android:id="@+id/top"
android:nextFocusUp="@+id/bottom"
... />
<Button android:id="@+id/bottom"
android:nextFocusDown="@+id/top"
... />
</LinearLayout>
一般情况下,在这个布局里,在第一个按钮上按上方向键哪儿都不会去,在第二个按钮上按下方向键也一样.现在通过nextFocusUp定义了它的上方向键聚焦对象为bottom(反过来也一样),所以焦点会上下循环移动.
如
果想在你的界面里声明一个可聚焦的View(当一般情况它不会被聚焦的时候), 添加android:focusable属性到这个View定义里去.把
值设置为true. 你也可以使用android:focusableInTouchMode属性在触摸模式下声明一个可聚焦的View.
需要设置焦点到某个View时,调用requestFocus()方法.
为了监听聚焦事件(当一个View得到或者失去焦点的时候收到通知),使用onFocusChange()方法,就像上面"事件监听器"部分所讨论的那样.
Android学习笔记--处理UI事件的更多相关文章
- Android学习笔记点击事件和触摸事件的区别
当我们点击手机屏幕的时候Android系统不仅会触发单击事件,还会触发触摸事件.在Android中它会先触发触摸事件,如果这个触摸事件没有被消费掉再去触发单击事件 代码示例: MainActivty. ...
- Android学习笔记长按事件的处理
常见的长按事件 代码示例: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedIns ...
- 【转】Pro Android学习笔记(十三):用户界面和控制(1):UI开发
目录(?)[-] UI开发 方式一通过XML文件 方式二通过代码 方式三XML代码 UI开发 先理清一些UI概念: view.widget.control:这三个名词其实没有什么区别,都是一个UI元素 ...
- Android学习笔记之Activity详解
1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...
- 【转】 Pro Android学习笔记(五五):调试和分析(3):adb命令、模拟器控制台和StrictMode
目录(?)[-] adb命令 模拟器Console StrictMode adb命令 我们在学习SQLite的使用,介绍过部分adb命令的使用,见Pro Android学习笔记(五):了解Conten ...
- 【转】 Pro Android学习笔记(三五):Menu(6):XML方式 & PopUp菜单
目录(?)[-] 利用XML创建菜单 XML的有关属性 onClick事件 Pop-up菜单 利用XML创建菜单 在代码中对每个菜单项进行设置,繁琐且修改不灵活,不能适配多国语言的要求,可以利用资源进 ...
- 【转】Pro Android学习笔记(三十):Menu(1):了解Menu
目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...
- 【转】Pro Android学习笔记(十二):了解Intent(下)
解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键 ...
- 【转】Pro Android学习笔记(二):开发环境:基础概念、连接真实设备、生命周期
在Android学习笔记(二):安装环境中已经有相应的内容.看看何为新.这是在source网站上的Android架构图,和标准图没有区别,只是这张图颜色好看多了,录之.本笔记主要讲述Android开发 ...
- android学习笔记36——使用原始XML文件
XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...
随机推荐
- JS-运动基础(一)续
2.淡入淡出的图片 用变量存储透明度 <title>无标题文档</title> <style> #div1{width:293px; height:220px; b ...
- java 接口与实现
Computable.java public interface Computable { int MAX = 46; int f(int x); } China.java public class ...
- PAT (Advanced Level) 1097. Deduplication on a Linked List (25)
简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...
- hdu_5738_Eureka(脑洞)
题目链接:hdu_5738_Eureka 题意: 这题感觉说不清楚,坑点有点坑,一不小心就会推出错误的公式,然后最重要的是你还不知道你推错了 题解: 这里贴一个官方的题解 Eureka xjb推导一下 ...
- hdu_5555_Immortality of Frog(状压DP)
题目连接:hdu_5555_Immortality of Frog 题意: 给你一个NxN的网格,第N行的每一列都有个青蛙,这些青蛙只会往上走,上帝会在每个膜中放一个长生不老的药,一共有N个膜,每个膜 ...
- Servlet程序开发--取得初始化配置信息
代码: 两个初始化init方法,一起出现的话,有参的才起作用 package org.lxh.servletdemo ; import java.io.* ; import javax.servlet ...
- SoftReference 介绍
1 Java中的SoftReference 2 即对象的软引用.如果一个对象具有软引用,内存空间足够,垃 圾回收器就不会回收它:如果内存空间不足了,就会回收这些对象的内存.只要垃圾回收器没有回收它,该 ...
- java集合框架list和set
为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一中方式 数组和集合类同是容器,有何不同? 数组虽然也可以存储对象 ...
- angularJS 系列(六)---$emit(), $on(), $broadcast()的使用
下面以一个例子来讲述 angular 中的event system,有$emit(), $on(), $broadcast().效果图如下 下面的代码中,用到了 controller AS 的语法,具 ...
- FACE++学习二、获得face属性
http://blog.csdn.net/lyq8479/article/details/17362685 为了防止网页丢失还是自己保存一份安全一点 人脸检测API介绍 在Face++网站的“API文 ...