Android输入事件详解
输入事件
在 Android 系统中,从用户与应用的交互中截获事件的方法不止一种。如考虑截获用户界面内的事件,则可从用户与之交互的特定视图对象中捕获事件。 为此,View 类提供了多种方法。
在您将用于构建布局的各种 View 类中,您可能会注意到几种看起来适用于 UI 事件的公共回调方法。 当该对象上发生相应的操作时,Android 框架会调用这些方法。 例如,在触摸一个视图对象(例如“按钮”)时,对该对象调用 onTouchEvent() 方法。不过,为了截获此事件,您必须扩展 View 类并重写该方法。 然而,为了处理此类事件而扩展每个视图对象并不现实。 正因如此,View 类还包含一系列嵌套接口以及您可以更加轻松定义的回调。 这些接口称为事件侦听器,是您捕获用户与 UI 之间交互的票证。
尽管您通常会使用事件侦听器来侦听用户交互,但有时您确实需要扩展 View 类以构建自定义组件。也许,您想扩展 Button 类来丰富某些内容的样式。 在这种情况下,您将能够使用该类的事件处理程序为类定义默认事件行为。
事件侦听器
事件侦听器是 View 类中包含一个回调方法的接口。 当用户与 UI 项目之间的交互触发已注册此视图的侦听器时,Android 框架将调用这些方法。
各事件侦听器接口包含的回调方法如下:
onClick()
在 View.OnClickListener 中。 当用户触摸项目(处于触摸模式下)时,或者使用导航键或轨迹球聚焦于项目,然后按适用的“Enter”键或按下轨迹球时,将调用此方法。
onLongClick()
在 View.OnLongClickListener 中。 当用户触摸并按住项目(处于触摸模式下)时,或者使用导航键或轨迹球聚焦于项目,然后按住适用的“Enter”键或按住轨迹球(持续一秒钟)时,将调用此方法。
onFocusChange()
在 View.OnFocusChangeListener 中。 当用户使用导航键或轨迹球导航到或远离项目时,将调用此方法。
onKey()
在 View.OnKeyListener 中。 当用户聚焦于项目并按下或释放设备上的硬按键时,将调用此方法。
onTouch()
在 View.OnTouchListener 中。 当用户执行可视为触摸事件的操作时,其中包括按下、释放或屏幕上的任何移动手势(在项目边界内),将调用此方法。
onCreateContextMenu()
在 View.OnCreateContextMenuListener 中。 当(因持续“长按”而)生成上下文菜单时,将调用此方法。请参见菜单开发者指南中有关上下文菜单的阐述。
这些方法是其相应接口的唯一成员。要定义其中一个方法并处理事件,请在 Activity 中实现嵌套接口或将其定义为匿名类。然后,将实现的实例传递给相应的 View.set…Listener() 方法。 (例如,调用 setOnClickListener() 并向其传递 OnClickListener 实现。)
以下示例显示了如何为按钮注册点击侦听器。
// 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);
...
}
您可能还会发现,将 OnClickListener 作为 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() 回调没有返回值,但是其他某些事件侦听器方法必须返回布尔值。具体原因取决于事件。
对于这几个事件侦听器,必须返回布尔值的原因如下:
onLongClick():此方法返回一个布尔值,表示您是否已处理完事件,以及是否应该将它继续传下去。 也就是说,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和/或事件应该继续传递给其他任何点击侦听器,则返回 false。
onKey():此方法返回一个布尔值,表示您是否已处理完事件,以及是否应该将它继续传下去。 也就是说,返回 true 表示您已经处理事件且事件应就此停止;如果您尚未处理事件和/或事件应该继续传递给其他任何按键侦听器,则返回 false。
onTouch(): 此方法返回一个布尔值,表示侦听器是否处理完此事件。重要的是,此事件可以拥有多个分先后顺序的操作。 因此,如果在收到关闭操作事件时返回 false,则表示您并未处理完此事件,而且对其后续操作也不感兴趣。 因此,您无需执行事件内的任何其他操作,如手势或最终操作事件。
请记住,硬按键事件总是传递给目前处于焦点的视图对象。它们从视图 层次结构的顶部开始分派,然后向下,直至到达合适的目的地。如果您的视图对象(或视图对象的子项)目前具有焦点,那么您可以看到事件经由 dispatchKeyEvent() 方法的分派过程。除了通过视图捕获按键事件,您还可以使用 onKeyDown() 和 onKeyUp() 接收 Activity 内部的所有事件。
此外
,考虑应用的文本输入时,请记住:许多设备只有软件输入法。 此类方法无需基于按键;某些可能使用语音输入、手写等。尽管输入法提供了类似键盘的界面,但它通常不会触发 onKeyDown() 系列的事件。除非您要将应用限制为带有硬键盘的设备,否则,在设计 UI 时切勿要求必须通过特定按键进行控制。 特别是,当用户按下返回键时,不要依赖这些方法验证输入;请改用 IME_ACTION_DONE 等操作让输入法知晓您的应用预计会作何反应,这样,可以通过一种有意义的方式更改其 UI。不要推断软件输入法应如何工作,只要相信它能够为应用提供已设置格式的文本即可。
注:Android 会先调用事件处理程序,然后从类定义调用合适的默认处理程序。 因此,从这些事件侦听器返回 true 会停止将事件传播到其他事件侦听器,还会阻止回调视图对象中的默认事件处理程序。 因此,在返回 true 时请确保您要终止事件。
事件处理程序
如果您从视图构建自定义组件,则将能够定义几种用作默认事件处理程序的回调方法。在有关自定义组件的文档中,您将了解某些用于事件处理的常见回调,其中包括:
onKeyDown(int, KeyEvent):在发生新的按键事件时调用
onKeyUp(int, KeyEvent):在发生按键弹起事件时调用
onTrackballEvent(MotionEvent):在发生轨迹球运动事件时调用
onTouchEvent(MotionEvent):在发生触摸屏运动事件时调用
onFocusChanged(boolean, int, Rect):在视图获得或失去焦点时调用
还有一些其他方法值得您注意,尽管它们并非 View 类的一部分,但可能会直接影响所能采取的事件处理方式。 因此,在管理布局内更复杂的事件时,请考虑使用以下其他方法:
Activity.dispatchTouchEvent(MotionEvent):此方法允许 Activity 在分派给窗口之前截获所有触摸事件。
ViewGroup.onInterceptTouchEvent(MotionEvent):此方法允许 ViewGroup 监视分派给子视图的事件。
ViewParent.requestDisallowInterceptTouchEvent(boolean): 对父视图调用此方法表明不应使用 onInterceptTouchEvent(MotionEvent) 截获触摸事件。
触摸模式
当用户使用方向键或轨迹球导航用户界面时,必须聚焦到可操作项目上(如按钮),以便用户看到将接受输入的对象。 但是,如果设备具有触摸功能且用户开始通过触摸界面与之交互,则不再需要突出显示项目或聚焦到特定视图对象上。 因此,有一种交互模式称为“触摸模式”。
对于支持触摸功能的设备,当用户触摸屏幕时,设备会立即进入触摸模式。 自此以后,只有 isFocusableInTouchMode() 为 true 的视图才可聚焦,如文本编辑小部件。其他可触摸的视图(如按钮)在用户触摸时不会获得焦点;按下时它们只是触发点击侦听器。
无论何时,只要用户点击方向键或滚动轨迹球,设备就会退出触摸模式并找到一个视图使其获得焦点。 现在,用户可在不触摸屏幕的情况下继续与用户界面交互。
整个系统(所有窗口和 Activity)都将保持触摸模式状态。要查询当前状态,您可以调用isInTouchMode() 来检查设备目前是否处于触摸模式。
处理焦点
该框架将处理例行焦点移动来响应用户输入。其中包括在视图被移除或隐藏时或在新视图变得可用时更改焦点。 视图对象表示愿意通过 isFocusable() 方法获得焦点。要设置视图能否获得焦点,请调用 setFocusable()。在触摸模式中,您可以使用 isFocusableInTouchMode() 查询视图是否允许聚焦,而且可以使用 setFocusableInTouchMode() 对此进行更改。
焦点移动所使用的算法会查找指定方向上距离最近的元素。 在极少数情况下,默认算法可能与开发者的期望行为不一致。 在这些情况下,您可以在布局文件中显式重写以下 XML 属性:nextFocusDown、nextFocusLeft、nextFocusRight 和 nextFocusUp。 将其中一个属性添加到失去焦点的视图。 将属性的值定义为应该聚焦的视图的 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(反之亦然),因而导航焦点将自上而下和自下而上循环往复。
若要将一个视图声明为在 UI 中可聚焦(传统上并非如此),请在布局声明中将 android:focusable XML 属性添加到该视图。将值设置为 true。 此外,您还可以使用 android:focusableInTouchMode 将视图声明为在触摸模式下可聚焦。
要请求要获得焦点的特定视图,请调用 requestFocus()。
要侦听焦点事件(视图获得或失去焦点时会收到通知),请使用 onFocusChange(), 如上文的事件侦听器部分中所述。
我的微信二维码如下,欢迎交流讨论
欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧
微信订阅号二维码如下:
Android输入事件详解的更多相关文章
- Android 广播大全 Intent Action 事件详解
Android 广播大全 Intent Action 事件详解 投稿:mrr 字体:[增加 减小] 类型:转载 时间:2015-10-20我要评论 这篇文章主要给大家介绍Android 广播大全 In ...
- Android GLSurfaceView用法详解(二)
输入如何处理 若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...
- android:ToolBar详解
android:ToolBar详解(手把手教程) 泡在网上的日子 发表于 2014-11-18 12:49 第 124857 次阅读 ToolBar 42 来源 http://blog.mosil.b ...
- Android之canvas详解
首先说一下canvas类: Class Overview The Canvas class holds the "draw" calls. To draw something, y ...
- 【转】Android Canvas绘图详解(图文)
转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡 ...
- js中鼠标滚轮事件详解
js中鼠标滚轮事件详解 (以下内容部分内容参考了http://adomas.org/javascript-mouse-wheel/ ) 之前js 仿Photoshop鼠标滚轮控制输入框取值中已使用 ...
- android屏幕适配详解
android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...
- Android Studio 插件开发详解一:入门练手
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78112003 本文出自[赵彦军的博客] 一:概述 相信大家在使用Android S ...
- Android系统目录结构详解
Android系统基于linux内核.JAVA应用,算是一个小巧精致的系统.虽是开源,但不像Linux一般庞大,娇小可亲,于是国内厂商纷纷开发出自己基于Android的操作系统.在此呼吁各大厂商眼光放 ...
随机推荐
- [LeetCode] Optimal Division 最优分隔
Given a list of positive integers, the adjacent integers will perform the float division. For exampl ...
- [LeetCode] Construct the Rectangle 构建矩形
For a web developer, it is very important to know how to design a web page's size. So, given a speci ...
- DDCTF 2018线上赛writeup
第一题: d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e ...
- 小白学习java设计模式之策略模式
策略模式:1.分析项目中的变化部分与不变部分(每个设计模式都要分析的)2.多用组合少用继承;用行为类组合,而不是行为继承,更具有弹性直接上代码: package com.wz.oneStrategis ...
- 【bzoj4008 hnoi2015】 亚瑟王
题目描述 小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑.他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟王是一个看脸的游戏,技能 ...
- bzoj 4518: [Sdoi2016]征途
Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜 ...
- ●HDU 6021 MG loves string
题链: http://acm.hdu.edu.cn/showproblem.php?pid=6021 题解: 题意:对于一个长度为 N的由小写英文字母构成的随机字符串,当它进行一次变换,所有字符 i ...
- 2393Cirno的完美算数教室 容斥
2393: Cirno的完美算数教室 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 652 Solved: 389[Submit][Status][ ...
- Java面试题—初级(8)
基本表结构: student(sno,sname,sage,ssex)学生表 course(cno,cname,tno) 课程表 sc(sno,cno,score) 成绩 ...
- C指针 指针和数组 二维数组的指针 指针应用
直接到变量名标识的存储单元中读取变量的值--直接寻址 通过其他变量间接找到变量的地址读取变量的值--间接寻址 指针变量存放地址 显示变量的地址 指针变量使用前必须初始化,若不知指向哪,可先指向NULL ...