文档章节

android事件处理

stephen_wu
 stephen_wu
发布于 2016/08/17 16:20
字数 2737
阅读 4
收藏 0
点赞 0
评论 0

刚开始学习android,最近看到一篇介绍事件处理的blog,转过来收藏。原文地址:http://www.360doc.com/content/16/0121/12/30309263_529522786.shtml

这一期主要集中学习了android的事件处理相关内容。主要参考内容为: Android 事件处理 Android核心技术与实例详解—事件处理 android的窗口机制分析------事件处理(该文属于android源码分析...

这一期主要集中学习了android的事件处理相关内容。主要参考内容为:

         Android 事件处理

        Android核心技术与实例详解—事件处理

         android的窗口机制分析------事件处理 (该文属于android源码分析级别,比较难,没完全看懂)

        Android开发指南-用户界面-事件处理

目的:通过全面的分析Android的鼠标和键盘事件。了解Android中如何接收和处理键盘和鼠标事件,以及如何用代码来产生事件。

主要学习内容:

1). 接收并处理鼠标事件:按下、弹起、移动、双击、长按、滑动、滚动

2). 接收并处理按键事件:按下、弹起

3). 模拟鼠标/按键事件

1. Android事件

        现代的用户界面,都是以事件来驱动的来实现人机交换的,而Android上的一套UI控件,无非就是派发鼠标和键盘事件,然后每个控件收到相应的事件之 后,做相应的处理。如Button控件,就只需要处理Down、move、up这几个事件,Down的时候重绘控件,move的时候一般也需要重绘控件, 当up的时候,重绘控件,然后产生onClick事件。在Android中通过实现OnClickListener接口的onClick方法来实现对 Button控件的处理。

        对于触摸屏事件(鼠标事件)有按下有:按下、弹起、移动、双击、长按、滑动、滚动。按下、弹起、移动(down、move、up)是简单的触摸屏事件,而 双击、长按、滑动、滚动需要根据运动的轨迹来做识别的。在Android中有专门的类去识 别,android.view.GestureDetector。

        对于按键(keyevent),无非就是按下、弹起、长按等。

2. Android事件处理

Android手机的坐标系是以左上定点为原点坐标(0,0), 向右为X抽正方形,向下为Y抽正方向。

       android平台的事件处理机制有两种:一种是基于回调的,一种基于事件监听的。当然还有更复杂的手势判别。

3. 事件侦听器Event Listeners

        事件侦听器是视图View类的接口,包含一个单独的回调方法。这些方法将在视图中注册的侦听器被用户界面操作触发时由Android框架调用。下面这些回调方法被包含在事件侦听器接口中:

onClick()

        包含于View.OnClickListener。当用户触摸这个item(在触摸模式下),或者通过浏览键或跟踪球聚焦在这个item上,然后按下“确认”键或者按下跟踪球时被调用。

onLongClick()

        包含于View.OnLongClickListener。当用户触摸并控制住这个item(在触摸模式下),或者通过浏览键或跟踪球聚焦在这个item上,然后保持按下“确认”键或者按下跟踪球(一秒钟)时被调用。

onFocusChange()

        包含于View.OnFocusChangeListener。当用户使用浏览键或跟踪球浏览进入或离开这个item时被调用。

onKey()

        包含于View.OnKeyListener。当用户聚焦在这个item上并按下或释放设备上的一个按键时被调用。

onTouch()

        包含于View.OnTouchListener。当用户执行的动作被当做一个触摸事件时被调用,包括按下,释放,或者屏幕上任何的移动手势(在这个item的边界内)。

onCreateContextMenu()

        包含于View.OnCreateContextMenuListener。当正在创建一个上下文菜单的时候被调用(作为持续的“长点击”动作的结果)。参阅创建菜单Creating Menus章节以获取更多信息。

        这些方法是它们相应接口的唯一“住户”。要定义这些方法并处理你的事件,在你的活动中实现这个嵌套接口或定义它为一个匿名类。然后,传递你的实现的一 个实例给各自的View.set...Listener() 方法。(比如,调用setOnClickListener()并传递给它你的OnClickListener实现。)

        注意上面提到的onClick()回调没有返回值,但是一些其它事件侦听器必须返回一个布尔值。原因和事件相关。对于其中一些,原因如下:

        1) onLongClick() – 返回一个布尔值来指示你是否已经消费了这个事件而不应该再进一步处理它。也就是说,返回true 表示你已经处理了这个事件而且到此为止;返回false 表示你还没有处理它和/或这个事件应该继续交给其他on-click侦听器。

        2) onKey() –返回一个布尔值来指示你是否已经消费了这个事件而不应该再进一步处理它。也就是说,返回true 表示你已经处理了这个事件而且到此为止;返回false 表示你还没有处理它和/或这个事件应该继续交给其他on-key侦听器。

        3)onTouch() - 返回一个布尔值来指示你的侦听器是否已经消费了这个事件。重要的是这个事件可以有多个彼此跟随的动作。因此,如果当接收到向下动作事件时你返回 false,那表明你还没有消费这个事件而且对后续动作也不感兴趣。那么,你将不会被该事件中的其他动作调用,比如手势或最后出现向上动作事件。

        记住按键事件总是递交给当前焦点所在的视图。它们从视图层次的顶层开始被分发,然后依次向下,直到到达恰当的目标。如果你的视图(或者一个子视图)当 前拥有焦点,那么你可以看到事件经由dispatchKeyEvent()方法分发。除了从你的视图截获按键事件,还有一个可选方案,你还可以在你的活动 中使用onKeyDown() and onKeyUp()来接收所有的事件。

        注意: Android 将首先调用事件处理器,其次是类定义中合适的缺省处理器。这样,从这些事情侦听器中返回true 将停止事件向其它事件侦听器传播并且也会阻塞视图中的缺事件处理器的回调函数。因此当你返回true时确认你希望终止这个事件。

        对于这些事件的具体例子,详见: Android核心技术与实例详解—事件处理

4. 事件处理器Event Handlers

        如果你从视图创建一个自定义组件,那么你将能够定义一些回调方法被用作缺省的事件处理器。在创建自定义组件Building Custom Components的文档中,你将学习到一些用作事件处理的通用回调函数,包括:

·onKeyDown(int, KeyEvent) - 当一个新的按键事件发生时被调用。

·onKeyUp(int, KeyEvent) - 当一个向上键事件发生时被调用。

·onTrackballEvent(MotionEvent) - 当一个跟踪球运动事件发生时被调用。

·onTouchEvent(MotionEvent) - 当一个触摸屏移动事件发生时调用。

·onFocusChanged(boolean, int, Rect) - 当视图获得或者丢失焦点时被调用。

        你应该知道还有一些其它方法,并不属于视图类的一部分,但可以直接影响你处理事件的方式。所以,当在一个布局里管理更复杂的事件时,考虑一下这些方法:

·Activity.dispatchTouchEvent(MotionEvent) - 这允许你的活动可以在分发给窗口之前捕获所有的触摸事件。

·ViewGroup.onInterceptTouchEvent(MotionEvent) - 这允许一个视图组ViewGroup 在分发给子视图时观察这些事件。

·ViewParent.requestDisallowInterceptTouchEvent(boolean) - 在一个父视图之上调用这个方法来表示它不应该通过onInterceptTouchEvent(MotionEvent)来捕获触摸事件。

        对于这些事件的具体例子,详见: Android核心技术与实例详解—事件处理

5. 手势识别

        很多时候,一个好的用户界面能够吸引用户的眼球。现在我们经常看到一些好的界面都带有滑动、滚动等效果。但是触摸屏是不可能产生滚动、滑动的消息的, 需要根据其运动的轨迹用算法去判断实现。在Android系统中,android.view.GestureDetector来实现手势的识别,我们只需 要实现其GestureDetector.OnGestureListener接口来侦听GestureDetector识别后的事件。我们需要在 onTouchEvent,GestureDetector的onTouchEvent方法是进行轨迹识别。

import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; public class TestEvent extends Activity { /** Called when the activity is first created. */ TextView m_eventType; int oldevent = -1; private GestureDetector gestureDetector= new GestureDetector(new OnGestureListener() { // 鼠标按下的时候,会产生onDown。由一个ACTION_DOWN产生。 public boolean onDown(MotionEvent event) { DisplayEventType('mouse down' + ' ' + event.getX() + ',' + event.getY()); return false; } // 用户按下触摸屏、快速移动后松开,这个时候,你的手指运动是有加速度的。 // 由1个MotionEvent ACTION_DOWN, // 多个ACTION_MOVE, 1个ACTION_UP触发 // e1:第1个ACTION_DOWN MotionEvent // e2:最后一个ACTION_MOVE MotionEvent // velocityX:X轴上的移动速度,像素/秒 // velocityY:Y轴上的移动速度,像素/秒 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { DisplayEventType('onFling'); return false; } // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发 public void onLongPress(MotionEvent event) { DisplayEventType('on long pressed'); } // 滚动事件,当在触摸屏上迅速的移动,会产生onScroll。由ACTION_MOVE产生 // e1:第1个ACTION_DOWN MotionEvent // e2:最后一个ACTION_MOVE MotionEvent // distanceX:距离上次产生onScroll事件后,X抽移动的距离 // distanceY:距离上次产生onScroll事件后,Y抽移动的距离 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { DisplayEventType('onScroll' + ' ' + distanceX + ',' + distanceY); return false; } //点击了触摸屏,但是没有移动和弹起的动作。onShowPress和onDown的区别在于 //onDown是,一旦触摸屏按下,就马上产生onDown事件,但是onShowPress是onDown事件产生后, //一段时间内,如果没有移动鼠标和弹起事件,就认为是onShowPress事件。 public void onShowPress(MotionEvent event) { DisplayEventType('pressed'); } // 轻击触摸屏后,弹起。如果这个过程中产生了onLongPress、onScroll和onFling事件,就不会 // 产生onSingleTapUp事件。 public boolean onSingleTapUp(MotionEvent event) { DisplayEventType('Tap up'); return false; } }); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); m_eventType = (TextView)this.findViewById(R.id.eventtype); } @Override public boolean onTouchEvent(MotionEvent event) { if(gestureDetector.onTouchEvent(event)) return true; else return false; } }

6、模拟鼠标/按键事件

Instrumentation发送键盘鼠标事件:Instrumentation提供了丰富的以send开头的函数接口来实现模拟键盘鼠标,如下所述:

sendCharacterSync(int keyCode)            //用于发送指定KeyCode的按键

sendKeyDownUpSync(int key)                //用于发送指定KeyCode的按键

sendPointerSync(MotionEvent event)     //用于模拟Touch

sendStringSync(String text)                   //用于发送字符串

Instrumentation inst=new Instrumentation();

inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 10, 10, 0));

inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 10, 10, 0));

© 著作权归作者所有

共有 人打赏支持
stephen_wu
粉丝 1
博文 40
码字总数 19561
作品 0
虹口
程序员
安卓自定义View进阶-事件分发机制原理

安卓自定义View进阶-事件分发机制原理 之前讲解了很多与View绘图相关的知识,你可以在 安卓自定义View教程目录 中查看到这些文章,如果你理解了这些文章,那么至少2D绘图部分不是难题了,大部...

猴亮屏 ⋅ 05/22 ⋅ 0

Android RxJava: 这是一份全面的 操作符 使用汇总 (含详细实例讲解)

前言 ,由于其基于事件流的链式调用、逻辑简洁 & 使用简单的特点,深受各大 开发者的欢迎。 如果还不了解RxJava,请看文章:Android:这是一篇 清晰 & 易懂的Rxjava 入门教程 如此受欢迎的原...

Carson_Ho ⋅ 05/31 ⋅ 0

Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析

每一个Activity组件都有一个关联的ContextImpl对象,同时,它还关联有一个Window对象,用来描述一个具体的应用程序窗口。与Activity组件所关联的窗口对象的实际类型为PhoneWindow。 那么创建...

lonamessi ⋅ 05/31 ⋅ 0

10分钟了解Android的事件分发

什么是事件分发? 大家知道Android中的视图是由一个个View嵌套构成的层级视图,即一个View里包含有子View,而这个子View里面又可以再添加View。当用户触摸屏幕产生一系列事件时,事件会由高到...

codeGoogle ⋅ 05/21 ⋅ 0

Android官方架构组件之LiveData + ViewModel + Room 源码分析一

简单使用案例: MainActivity: MessageViewModel: 其中viewModel.getMessageObserver().observe(this, new Observer() ) 中的this即SupportActivity :LifecycleOwner SupportActivity im......

编程之乐 ⋅ 05/23 ⋅ 0

监听android:drawableLeft和android:drawableRight点击事件

监听android:drawableLeft和android:drawableRight点击事件 Android官方没有提供对android:drawableLeft和android:drawableRight点击事件的监听,但有些情况下,如下面的搜索栏, 需要在用户...

zhangphil ⋅ 04/17 ⋅ 0

我的Android重构之旅:架构篇

EF A舞蹈服 去年10月底来到了新公司,刚开始接手 Android 项目时,发现该项目真的是一团遭,项目开发上没有任何架构可言,开发人员连简单的 MVC、MVP 都不了解,Activity 及其臃肿,业务边界...

codeGoogle ⋅ 05/31 ⋅ 0

Design Patterns in Android:责任链模式

前言 非常抱歉,本系列博客长达半年没更新了,今日偶得灵感,更新一波《设计模式Android篇:责任链模式》。点击此处查看《Design Patterns in Android》系列其他文章。 本文原创作者MichaelX。...

MichaelX ⋅ 05/14 ⋅ 0

Android dispatchTouchEvent检测多点触摸事件是否落入在某一个View区域内

Android dispatchTouchEvent检测多点触摸事件是否落入在某一个View区域内 检测发生在Android设备屏幕上到的点击事件是否发生在某一个View的区域内,重点方法是touchEventInView,该方法进行具...

zhangphil ⋅ 04/24 ⋅ 0

理解 Android Hook 技术以及简单实战

什么是 Hook Hook 英文翻译过来就是「钩子」的意思,那我们在什么时候使用这个「钩子」呢?在 Android 操作系统中系统维护着自己的一套事件分发机制。应用程序,包括应用触发事件和后台逻辑处...

猴亮屏 ⋅ 04/17 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

spring Email

使用spring发Email其实就是使用spring自己封装携带的一个javamail.JavaMailSenderImpl类而已。这个类可以当一个普通的java对象来使用,也可以通过把它配置变成spring Bean的方式然后注入使用...

BobwithB ⋅ 14分钟前 ⋅ 0

spark 整理的一些知识

Spark 知识点 请描述spark RDD原理与特征? RDD全称是resilient distributed dataset(具有弹性的分布式数据集)。一个RDD仅仅是一个分布式的元素集合。在Spark中,所有工作都表示为创建新的...

tuoleisi77 ⋅ 17分钟前 ⋅ 0

思考

时间一天天过感觉自己有在成长吗?最怕的是时光匆匆而过,自己没有收获!下面总结下最近自己的思考。 认识自己 认识另一个自己,人们常说要虚心听取别人意见和建议。然而人往往是很难做到的,...

hello_hp ⋅ 18分钟前 ⋅ 0

IT行业的变革就像世界杯德国对战墨西哥一样难以预测[图]

最近在观看世界杯,尤其是昨天的比赛,上一届卫冕冠军德国队居然0:1告负墨西哥,这创造了历史,首先是墨西哥从来没赢过德国队,其次是德国队36年来首站没输过,再差也是打平,而这次,德国队...

原创小博客 ⋅ 37分钟前 ⋅ 0

解决CentOS6、7,/etc/sysconfig/下没有iptables的问题

一、Centos 6版本解决办法: 1.任意运行一条iptables防火墙规则配置命令: iptables -P OUTPUT ACCEPT 2.对iptables服务进行保存: service iptables save 3.重启iptables服务: service ...

寰宇01 ⋅ 47分钟前 ⋅ 2

数据库备份和恢复

备份:mysqldump -u root -p 数据库>磁盘路径 恢复:mysql -u root -p 数据库<sql脚本的磁盘路径

anlve ⋅ 今天 ⋅ 0

发生了什么?Linus 又发怒了?

在一个 Linux 内核 4.18-rc1 的 Pull Request 中,开发者 Andy Shevchenko 表示其在对设备属性框架进行更新时,移除了 union 别名,这引发了 Linus 的暴怒。 这一次 Linus Torvalds 发怒的原...

问题终结者 ⋅ 今天 ⋅ 0

在树莓派上搭建一个maven仓库

在树莓派上搭建一个maven仓库 20180618 lambo init 项目说明 家里有台树莓派性能太慢。想搭建一个maven私服, 使用nexus或者 jfrog-artifactory 运行的够呛。怎么办呢,手写一个吧.所在这个...

林小宝 ⋅ 今天 ⋅ 0

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部