回调机制

如果说事件监听机制是一种委托式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源与事件监听器是统一的,换种方法说事件监听器完全消失了,当用户在GUI组件上激发某个事件时,组件自己特定的方法将会负责处理该事件。

使用回调机制类处理GUI组件上所发生的事件时,我们需要为该组件提供所对应的事件处理方法--该事件处理方法通常都是系统预先定义好的,因此通常需要继承GUI组件类,并通过重写该类的处理方法来实现。

为了实现回调机制的事件处理,Android为所有GUI组件都提供了一些事件处理的回调方法,以View为例,该类有如下方法:

  • boolean onKeyDown(int keyCode,KeyEvent event);当用户在该组件按下某个按键时触发该方法。
  • boolean onKeyLongPress(int keyCode,KeyEvent event);当用户在该组件长按下某个按键时触发该方法。
  • boolean onKeyShorcut(int keyCode,KeyEvent event);当一个键盘快捷键事件发生时触发该方法。
  • boolean onKeyUp(int keyCode,KeyEvent event);当用户在该组件上松开某个按键时触发该方法。
  • boolean onTouchEvent(MotionEvent event);当用户在该组件触发触摸屏事件时触发该方法。
  • boolean onTrackballEvent(MotionEvent event);当用户在该组件上触发轨迹球事件时触发该方法。

如下的程序展示了基于回调的事件处理机制。正如前面所提到的,基于回调的事件处理机制可以通过自定义View来实现,自定义View时重写该View的事件处理方法即可。

MyButton.java

 public class MyButton extends Button
{
public MyButton(Context context, AttributeSet set)
{
super(context, set);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
Log.v("-com.example-", "the onTouchEvent in MyButton");
// 返回true,表明该事件不会向外传播
return true;
}
}

在上面自定义的MyButton类中,我们重写了Button类的onTouchEvent(MotionEvent event)方法,该方法将会负责处理按钮上的用户触碰事件。

部分界面文件如下。

 <!-- 使用自定义View时应使用全限定类名 -->
<org.crazyit.event.MyButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="单击我" />

运行上面的程序在Logcat有如下显示

基于回调的事件传播

几乎所有基于回调的事件处理方法都有一个Boolean类型的返回值,该返回值用于标识该处理方法能否完全处理该事件。

  • 如果处理事件返回true,则表明处理方法已经完全处理该事件,该事件不会传播出去。

  • 如果处理事件返回false,则表明处理方法并未完全处理该事件,该事件会传播出去。

对于基于回调的事件传播而言某组件上所发生的事件不仅会激发该组件上的回调方法,也会触发该组件所在Activity的回调方法--只要事件能传播到Activity。

如下的程序示范了Android系统中的事件传播,重写Button类的处理方法时没有阻止事件传播,因此能看到事件从Button传播到Activity的情形。

MyButton.java

 public class MyButton extends Button
{
public MyButton(Context context, AttributeSet set)
{
super(context, set);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
Log.v("-com.example-", "the onTouchEvent in MyButton");
// 返回false,表明该事件会向外传播
return false; // ①
}
}

上面的MyButton子类重写了onTouchEvent方法,当用户触碰该按钮时将会触发该方法,但由于该方法返回了false,这意味着事件还会继续向外传播。

接下来看下Activity类代码

 public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bn = findViewById(R.id.bn);
bn.setOnTouchListener((view, event) ->
{
// 只处理按下键的事件
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.v("--Listener--", "the TouchDown in Listener");
}
// 返回false,表明该事件会向外传播
return true;
});
}
// 重写onTouchEvent方法,该方法可监听它所包含的所有组件上的触碰事件
@Override
public boolean onTouchEvent(MotionEvent event)
{
super.onTouchEvent(event);
Log.v("--Activity--", "the onTouchEvent in Activity");
// 返回false,表明该事件会向外传播
return false;
}
}

运行上面的程序,触碰按钮,可以在Logcat中看的如下的输出。

从上图中不难看出,当该组件发生触碰事件时,Android系统最先触发的应该是组件绑定的监听器,然后再触发组件提供的事件回调方法,最后还会传播到该组件所在的Activity。但如果任何一个事件处理方法返回了true,那么该事件都不会继续向外传播。例如改写监听器代码,返回为true,然后再运行并触碰按钮,那么在Logcat上会看的如下的输出。

注:本文部分内容参考《疯狂Android讲义》一书,侵权必删

Android的事件处理机制之基于回调的事件处理的更多相关文章

  1. Android笔记二十四.Android基于回调的事件处理机制

        假设说事件监听机制是一种托付式的事件处理,那么回调机制则与之相反,对于基于回调的事件处理模型来说,事件源和事件监听器是统一的,或者说事件监听器全然消失了,当用户在GUI控件上激发某个事件时,控 ...

  2. Android零基础入门第35节:Android中基于回调的事件处理

    原文:Android零基础入门第35节:Android中基于回调的事件处理 通过前面两期掌握了Android中基于监听的事件处理的五种形式,那么本期一起来学习Android中基于回调的事件处理. 一. ...

  3. Android的事件处理机制之基于监听的事件处理

    无论是桌面应用还是手机应用程序,面对用户的使用,经常需要处理的便是用户的各种动作,也就是需要为用户动作提供响应,这种为用户动作提供响应的机制就是事件处理. 而Android为我们提供了两套强大的响应机 ...

  4. 基于回调的事件处理——重写onTouchEvent方法响应触摸屏事件

    对于Android提供的事件处理模型,不难发现基于监听的事件处理模型具有更大的优势: 基于监听的事件模型分工更加明确,事件源.事件监听有两个类分开实现,因此具有更好的维护性. Android的事件处理 ...

  5. Android学习笔记基于回调的事件处理

    流程: 常见的回调方法: 代码示例: @Override public boolean onTouchEvent(MotionEvent event) { Toast.makeText(getAppl ...

  6. Android的两种事件处理机制

    UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理. 对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事 ...

  7. Android的事件处理机制详解(二)-----基于监听的事件处理机制

    基于监听的事件处理机制 前言: 我们开发的app更多的时候是需要与用户的交互----即对用户的操作进行响应 这就涉及到了android的事件处理机制; android给我们提供了两套功能强大的处理机制 ...

  8. Android事件处理机制

    包括监听和回调两种机制. 1. 基于监听的事件处理: 事件监听包含三类对象,事件源,事件,事件监听器.Android的事件处理机制是一种委派式(Delegation)事件处理方式:普通组件(事件源)将 ...

  9. Android——基于监听器的事件处理(转)

    事件,我们并不陌生! 所有的基于UI的应用程序,事件都变得不可或缺!试想一下,如果我们做的程序单击按钮和其它控件都没有反应,那么就如同一个人在这个世界上听不到声音一样! Android为我们提供了两种 ...

随机推荐

  1. C++的const成员函数

    我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误.例如, const char blank = ‘’; blank = ‘\n’;  // 错误 面向对象 ...

  2. selenium webdriver 常用方法

    /** * 判断元素是否存在 * * @param driver * @param by * @return */ public static boolean isElementPresent(Web ...

  3. WebService-CXF 学习笔记

    什么是CXF Apache CXF = Celtix + Xfire支持多种协议:SOAP1.1,1.2XML/HTTPCORBA(Common Object Request Broker Archi ...

  4. Node Sass does not yet support your current environment: Linux 64-bit with Unsupported runtime

    环境: ubuntu18 webstorm vue项目 报错原因: 缺少相关依赖 解决方法: npm rebuild node-sass 还未解决: npm uninstall --save node ...

  5. Myeclipse创建HTML文件中文显示乱码问题

    例如 运行结果 错误原因 不同浏览器的,编码格式不同 解决方法 运行结果 通常charset的设值我们常用的有gb2312,gbk,utf-8三种,即有三种编码规定: <meta http-eq ...

  6. 最大流EK板子

    #include <bits/stdc++.h> using namespace std; ; const int INF=0x7fffffff; typedef long long ll ...

  7. 找出crontab表达式内符合的下一次出发时间点(经典!!!)

    参考: https://blog.csdn.net/crazycoder2010/article/details/7905848

  8. struts标签 解析html标签

    参考:http://blog.csdn.net/shuangrenyu1234/article/details/24527745

  9. Linux--info命令 ,help命令,man命令(帮助)

    Info和man命令一样都是帮助类文件 Info文件不仅包含信息,而且还包含连接到其他info文件的链接. 如何使用info显示希望的内容 * 如何操纵Info系统 * 如何显示Info的帮助信息. ...

  10. tensorflow文本分类实战——卷积神经网络CNN

    首先说明使用的工具和环境:python3.6.8   tensorflow1.14.0   centos7.0(最好用Ubuntu) 关于环境的搭建只做简单说明,我这边是使用pip搭建了python的 ...