Android中的事件侦听器 学习笔记

自己实验
然后自己对这几个事件侦听器做了测试
代码就不贴了 直接看效果吧 要不然页数太多了
当我单击按钮时

在这里插入图片描述

当我长按按钮时
在这里插入图片描述
这里我设置了返回值为true 所以事件会被消费 不会继续分发 但是如果我设置为false 他就会继续分发 假如我有单击事件 他将会被单击事件消费

当我光标点击输入框1时
在这里插入图片描述
当我光标点击输入框2时
在这里插入图片描述

然后时key事件

我不知道为什么当我 输入字母的时候他不会触发 只有 回车 删除 方向键有效果

在这里插入图片描述
在这里插入图片描述

Touch事件 (就是手指触摸时) 我没有试在手机上多出触摸会发生什么

在这里插入图片描述

然后是上下文菜单测试 长按后会出现一个菜单

在这里插入图片描述
在这里插入图片描述

选中后就改变第一个txt的文字

然后我们每次长按后都会调用onCreateContextMenu
创建
在这里插入图片描述

Android事件侦听器
转载 http://developer.51cto.com/art/201001/180846.htm

Android事件侦听器作为视图View类的接口,其中包含有不少回调方法,比如:onClick();onLongClick();onFocusChange();onKey();onTouch();onCreateContextMenu()等等。

Android操作系统中,对于事件的处理是一个非常基础而且重要的操作。许多功能的实现都需要对相关事件进行触发才能达到自己的目的。比如Android事件侦听器是视图View类的接口,包含一个单独的回调方法。这些方法将在视图中注册的侦听器被用户界面操作触发时由Android框架调用。下面这些回调方法被包含在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。当正在创建一个上下文菜单的时候被调用(作为持续的“长点击”动作的结果)。

这些方法是它们相应接口的唯一“住户”。要定义这些方法并处理你的事件,在你的活动中实现这个嵌套接口或定义它为一个匿名类。然后,传递你的实现的一个实例给各自的View.set…Listener() 方法。(比如,调用setOnClickListener()并传递给它你的OnClickListener实现。)
下面的例子说明了如何为一个按钮注册一个点击侦听器:

1.// Create an anonymous implementation of OnClickListener
2.private OnClickListener mCorkyListener = new OnClickListener() {
3.public void onClick(View v) {
4.// do something when the button is clicked
5.}
6.};
7.protected void onCreate(Bundle savedValues) {
8…
9.// Capture our button from layout
10.Button button = (Button)findViewById(R.id.corky);
11.// Register the onClick listener with the implementation above
12.button.setOnClickListener(mCorkyListener);
13…
14.}

你可能会发现把OnClickListener作为活动的一部分来实现会便利的多。这将避免额外的类加载和对象分配。比如:

1.public class ExampleActivity extends Activity implements OnClickListener {
2.protected void onCreate(Bundle savedValues) {
3…
4.Button button = (Button)findViewById(R.id.corky);
5.button.setOnClickListener(this);
6.}
7.// Implement the OnClickListener callback
8.public void onClick(View v) {
9.// do something when the button is clicked
10.}
11…
12.}

注意上面例子中的onClick()回调没有返回值,但是一些其它Android事件侦听器必须返回一个布尔值。原因和事件相关。对于其中一些,原因如下:
· onLongClick() – 返回一个布尔值来指示你是否已经消费了这个事件而不应该再进一步处理它。也就是说,返回true 表示你已经处理了这个事件而且到此为止;返回false 表示你还没有处理它和/或这个事件应该继续交给其他on-click侦听器。
· onKey() –返回一个布尔值来指示你是否已经消费了这个事件而不应该再进一步处理它。也就是说,返回true 表示你已经处理了这个事件而且到此为止;返回false 表示你还没有处理它和/或这个事件应该继续交给其他on-key侦听器。
· onTouch() - 返回一个布尔值来指示你的侦听器是否已经消费了这个事件。重要的是这个事件可以有多个彼此跟随的动作。因此,如果当接收到向下动作事件时你返回false,那表明你还没有消费这个事件而且对后续动作也不感兴趣。那么,你将不会被该事件中的其他动作调用,比如手势或最后出现向上动作事件。
记住按键事件总是递交给当前焦点所在的视图。它们从视图层次的顶层开始被分发,然后依次向下,直到到达恰当的目标。如果你的视图(或者一个子视图)当前拥有焦点,那么你可以看到事件经由dispatchKeyEvent()方法分发。除了从你的视图截获按键事件,还有一个可选方案,你还可以在你的活动中使用onKeyDown() and onKeyUp()来接收所有的事件。
注意: Android 将首先调用事件处理器,其次是类定义中合适的缺省处理器。这样,从这些事情侦听器中返回true 将停止事件向其它Android事件侦听器传播并且也会阻塞视图中的缺事件处理器的回调函数。因此当你返回true时确认你希望终止这个事件。

Android中的事件分发(View事件的分发)

转载:https://github.com/DmrfCoder/interview/blob/master/Android/Android.md

1.思想:委托子View处理,子View不能处理则自己处理
2.委托过程:activity -> window -> viewGroup -> view
3.处理事件方法的优先级:onTouchListener > onTouchEvent > onClickListener
完整的事件通常包括Down、Move、Up,当down事件被拦截下来以后,move和up就不再走intercept方法,而是直接被传递给当前view处理
事件分发的对象是点击事件,当用户触摸屏幕时(View 或 ViewGroup派生的控件),将产生点击事件(Touch事件),而Touch事件的相关细节(发生触摸的位置、时间等)被封装成MotionEvent对象,对应的事件类型有4种:
事件类型 具体动作
MotionEvent.ACTION_DOWN 按下View(所有事件的开始)
MotionEvent.ACTION_UP 抬起View(与DOWN对应)
MotionEvent.ACTION_MOVE 滑动View
MotionEvent.ACTION_CANCEL 结束事件(非人为原因)
事件列:从手指接触屏幕 至 手指离开屏幕,这个过程产生的一系列事件,一般情况下,事件列都是以DOWN事件开始、UP事件结束,中间有0个或多个的MOVE事件。
事件分发的本质:将点击事件(MotionEvent)传递到某个具体的View & 处理的整个过程

事件分发中的三个重要方法:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent
方法 方法中文名 解释 返回值
dispatchTouchEvent(MotionEvent ev) 事件分发 用来进行事件的分发。如果事件能够传递给当前View,那么此方法一定会被调用,返回结果受当前View的onTouchEvent和下级View的DispatchTouchEvent方法的影响,表示是否消耗当前事件。 return true :表示该View内部消化掉了所有事件。
return false :事件在本层不再继续进行分发,并交由上层控件的onTouchEvent方法进行消费(如果本层控件已经是Activity,那么事件将被系统消费或处理)。
如果事件分发返回系统默认的 super.dispatchTouchEvent(ev),事件将分发给本层的事件拦截onInterceptTouchEvent 方法进行处理
onInterceptTouchEvent(MotionEvent event) 事件拦截 在上述方法内部调用,用来判断是否拦截某个事件,如果当前View拦截了某个事件,那么在同一个事件序列当中,此方法不会被再次调用,返回结果表示是否拦截当前事件。 return true :表示将事件进行拦截,并将拦截到的事件交由本层控件 的 onTouchEvent 进行处理;
return false :则表示不对事件进行拦截,事件得以成功分发到子View。并由子View的dispatchTouchEvent进行处理。 
如果返回super.onInterceptTouchEvent(ev),默认表示拦截该事件,并将事件传递给当前View的onTouchEvent方法,和return true一样。
onTouchEvent(MotionEvent event) 事件响应 在dispatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列中,当前View无法再次接收到事件
三者的关系可以总结为如下伪代码:
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume = false;
if (onInterceptTouchEvent(ev)) {
consume = onTouchEvent(ev);
} else {
consume = child.dispatchTouchEvent(ev);
}

return consume;

}

一个事件序列只能被一个View拦截且消耗,不过通过事件代理TouchDelegate,可以将onTouchEvent强行传递给其他View处理。
某个View一旦决定拦截,那么这一事件序列就都只能由它来处理。
某个View一旦开始处理事件,如果不消耗ACTION_DOWN事件(onTouchEvent返回了false),那么事件会重新交给它的父元素处理,即父元素的onTouchEvent会被调用。
完整的事件通常包括Down、Move、Up,当down事件被拦截下来以后,move和up就不再走intercept方法,而是直接被传递给当前view处理
ViewGroup默认不拦截任何事件。Android源码中ViewGroup的onInterceptTouchEvent`方法默认返回false。
View没有onIntercepteTouchEvent方法,一旦有点击事件传递给它,那么它的onTouchEvent方法就会被调用。
什么时候执行ACTION_CANCEL
1.一个点击或者活动事件包含ACTION_DOWN,ACTION_MOVE,ACTION_UP等
2.当子View处理了ACTION_DOWN事件之后,后续的ACTION_MOVE,ACTION_UP都会直接交由这个子View处理
3.如果此时父View拦截了ACTION_MOVE,ACTION_UP,那么子View会收到一个ACTION_CANCEL
4.场景举例:点击一个控件,并滑动到控件外,此时次控件会收到一个ACTION_CALNCEL
滑动冲突
外部拦截:重写onInterceptTouchEvent方法 内部拦截:重写dispatchTouchEvent方法,同时配合requestDisAllowInterceptTouchEvent方法
requestDisAllowInterceptTouchEvent:子view可以通过设置此方法去告诉父view不要拦截并处理点击事件,父view应该接受这个请求直到此次点击事件结束。
两指缩放
1.为了解决多点触控问题,android在MotionEvent中引入了pointer概念
2.通过ACTION_DOWN、ACTION_POINTER_DOWN、ACTION_MOVE、ACTION_POINTER_UP、ACTION_UP来检测手机的动作
3.每个手指的位置可以通过getX(pointIndex)来获得,这样我们就能判断出滑动的距离
4.缩放有多种实现: 1. ImageView可以通过setImageMatrix(martix)来实现 2. 自定义View可以缩放Canvas的大小 3. 还可以设置LayoutParams来改变大小
多点触控的要点:
在onTouch(Event event)中通过event.getPointerCount,可以获得触摸点的个数,通过event.getX(index),添加索引可以获得不同控制点的坐标,然后做自己需要的事情。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值