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()方法,就像上面"事件监听器"部分所讨论的那样.

转载于:https://www.cnblogs.com/awodefeng/p/3408670.html

Android学习笔记--处理UI事件相关推荐

  1. ANDROID 学习笔记(三) UI THREAD AsyncTask 使用

    为什么80%的码农都做不了架构师?>>>    一般获取验证码,用户登录验证,上传头像,获取消息,发消息,评论 都可以使用 1.先上官网实例代码 private class Down ...

  2. Android学习笔记(Android Studio)3-3(ProgressBar ProgressDialog)(加载进度条、转圈圈)UI组件之弹出组件

    Android学习笔记3-3 推荐新手向学习视频:B站https://www.bilibili.com/video/av38409964点我传送 3-3 ProgressBar & Progr ...

  3. Android学习笔记 2.5.3 实例——使用SimpleAdapter创建ListView 2.5.4 自动完成文本框(AutoCompleteTextView)的功能与用法

    Android学习笔记 疯狂Android讲义 文章目录 Android学习笔记 疯狂Android讲义 第2章 Android 应用的界面编程 2.5 第4组 UI组件:AdapterView及其子 ...

  4. Android学习笔记:Android基础知识点(不断更新中)

    1.Android学习笔记:OkHttp 2.Android学习笔记:更新UI的方法(UI线程和非UI线程) 3.Android学习笔记:Volley 4.Android学习笔记:Handler 5. ...

  5. Android学习笔记第五篇--网络连接与云服务(一)

    Android学习笔记第五篇–网络连接与云服务 第一章.无线连接设备 ​ 除了能够在云端通讯,Android的无线API也允许在同一局域网内的设备通讯,**甚至没有连接网络,而是物理具体相近,也可以相 ...

  6. Android学习笔记26:图片切换控件ImageSwitcher的使用

    在Windows操作系统中,要查看多张图片,可以通过使用"Windows照片查看器"在"上一张"和"下一张"之间切换,进行多张图片的浏览. ...

  7. Android学习笔记36:使用SQLite方式存储数据

    在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...

  8. Android学习笔记:TabHost 和 FragmentTabHost

    2019独角兽企业重金招聘Python工程师标准>>> Android学习笔记:TabHost 和 FragmentTabHostTabHost命名空间:android.widget ...

  9. Android学习笔记:TabHost 和 FragmentTabHost(转)

    Android学习笔记:TabHost 和 FragmentTabHost(转) 转自:http://www.cnblogs.com/asion/p/3339313.html 作者:Asion Tan ...

  10. Android学习笔记(四九):通过Content Provider访问数据

    在上次笔记中,我们编写了自己的Provider,这次笔记,我们将通过Content Provider的Uri接口对数据进行访问,重写Android学习笔记(四二)中例子.在这里我们不在充分描述相关UI ...

最新文章

  1. Html篇-fieldset标签演示
  2. 解决git@osc每次提交需要输入用户名密码的问题
  3. js array 对象
  4. 试试看 ? 离奇古怪的javascript题目
  5. 求助!!css选择器为什么有很多标签查不到
  6. 如何降低微服务测试成本?
  7. Jquery-基础知识点
  8. Reverse原理背后的数学和魔幻艺术
  9. git登录相关操作梳理
  10. OpenCV:分离图像和视频的RGB通道
  11. python assert
  12. 查询SQL中日期条件
  13. python查看汉字的编码_python汉字编码
  14. 从零开始系类——模拟电子技术
  15. 激活Window和office工具
  16. 010Editor相关
  17. cad如何多选对象_CAD如何快速选择对象
  18. 将一个数组划分成总和相等的两部分
  19. 【鼠标事件 MouseEvent】clientX clientY offsetX offsetX pageX screenX screenY
  20. 计算机考研面试有英语听力吗,考研复试前如何准备英语听力和口语

热门文章

  1. 蓝桥杯:入门训练 序列求和
  2. linux mysql 自动加斜杠_【实战演练】Linux操作系统19-Mysql主主复制加Keepalived高可用...
  3. wpf每隔一小时_包河区徐河排涝站24小时不间断运作 11座区管泵站全面应战保安澜...
  4. debug控制台内容消失 idea_IDEA 乱码问题(解决方案篇)
  5. android sco通信,android – startBluetoothSco()在ICS上抛出安全异常(BROADCAST_STICKY)
  6. android studio 单步调试jni,android studio实现Jni单步调试-标准配置教程
  7. python官网支持货到付款吗_官网购买的iPhone12pro还没发货?试着用Python快速入手...
  8. C++知识点23——使用C++标准库(顺序容器list的其他操作)
  9. 打印机是微型计算机必须配置的一种,计算机第一章测试卷
  10. 手摸手,带你用 vue 动画实现原生 app 切换效果,丝滑般的体验