全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

老生常谈android中的事件传递和处理机制

一直以来,都被android中的事件传递和处理机制深深的困扰!今天特意来好好的探讨一下。现在的感觉是,只要你理解到位,其实事件的

传递和处理机制并没有想象中的那么难。总之,不要自己打击自己,要相信自己能掌握这块知识。好了,下面是我今天的收获,希望也

能对你有一点帮助。

一、拟人化来理解android中的事件机制

其实android中的事件传递与处理机制跟我们生活中的事件处理是一样的。这里有一个生活中的例子,很能说明这个问题。阐述如下:

你是一个公司的员工,你的上头有一个主管,主管上头呢还有一个经理。为了简单,你们这个团队就有这三个人。那么如果上头安排一件事下来要处理,流程是怎样的呢?显然应该是由你的经理将这件事安排给你的主管来处理,你的主管再将这件事安排给你来处理。等你把这件事办好了,你就应该给你的主管报告,再由你的主管来向你的经理报告。显然,你的主管和经理也有处理这件事的权限,如果他们觉得事情很复杂,你办不了,或者他们比较照顾下级,可能就自己把这件事给办了,这个时候这件事就不会再传递给下一级来处理了。这个事件处理的过程,是不是太容易理解了!

其实android中的事件处理流程就是跟生活中的事件处理是一样的。比如你在ViewGroupA中嵌套了一个VewiGroupB,然后又在ViewGroupB

中嵌套了一个MyView。那么一个触摸事件传递过来,会发生什么情况呢?类比上面的公司员工的处理事件,显然会发生下面的过程:

触摸事件传递过来后,ViewGroupA一看自己里面还有一个员工可以利用,就是ViewGroupB,那不用白不用,就会把这个事件传递给ViewGroupB,告诉他,你给我把这个事件处理了!

ViewGroupB呢一看,我不怕,我里面也有一个员工就是MyView,它得给我干活,于是又会把这个事件传递给MyView,让它来处理。MyView一看,没办法啊,我手底下没有员工了,那怎么办,我只能自己处理了(前提是它有处理这个事件的能力),所以就把这个触摸事件给处理了。处理完成后呢?MyView就是给ViewGroupB报告,我已经把事情办好了,你来审核一下
,看看办理的咋样。ViewGroupB一审核,觉得不错,就再将结果呈现给ViewGroupA。ViewGroupA再审核,通过了才算通过。在这个过程中,也可能出现几种情况:

(1)MyView说,完蛋了,这事我的能力办不好啊,于是就向VeiwGroupB报告,我没有处理,请你来处理,你是我上司,能力比我强。于是ViewGroupB就会来帮忙处理。当然了,

如果ViewGroupB也没能力处理,那就只能反馈给VeiwGroupA,让它来消化这个事件。

(2)也可能MyView处理非常完美,向ViewGroupB一报告,ViewGroupB一开心就说不用再交给ViewGroupA审核了,我担保通过,于是事件到此直接终止。

上面用很形象的话来讲adnroid中的事件传递和处理机制讲解了一下。android用下面的几个方法将上面的过程完美封装了:

在ViewGroup中,有下面三个方法:
(1)dispatchTouchEvent   该方法用来分发事件,一般不会重写这个方法
(2)onInterceptTouchEvent 用来拦截事件
(3)onTouchEvent      用来处理事件,这个方法应该大家很常见了吧

而View中,只有两个方法,即:(1)dispatchTouchEvent   该方法用来分发事件,一般不会重写这个方法
(2)onTouchEvent      用来处理事件,这个方法应该大家很常见了吧

那么我们就来写一个实际的代码,来验证一下这些方法都对应上面的哪些过程。这样子就会对这个些方法有更透彻的理解。

二、根据实战代码来分析各个方法

下面我们就来把上面提到的ViewGroupA,ViewGroupB,还有MyView给编写出来。

新建一个项目,先来写ViewGruopA,代码如下:

package com.example.testmotionevent;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class ViewGroupA extends LinearLayout{

  public ViewGroupA(Context context) {
    super(context);
  }
  public ViewGroupA(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
  public ViewGroupA(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }
  
  
  

  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    
    Log.d("付勇焜----->","ViewGroupA dispatchTouchEvent");
    return super.dispatchTouchEvent(ev);
  }
  
  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    
    Log.d("付勇焜----->","ViewGroupA onInterceptTouchEvent");
    return super.onInterceptTouchEvent(ev);
  }
  
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    Log.d("付勇焜----->","ViewGroupA onTouchEvent");
    return super.onTouchEvent(event);
  }
}

代码很简单,就不用我解释了吧,无非就是重写上面提到的那几个方法,然后打印相关的标记,来观察事件的处理机制。

同理,编写ViewGroupB,如下:

package com.example.testmotionevent;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class ViewGroupB extends LinearLayout{

  public ViewGroupB(Context context) {
    super(context);
  }
  public ViewGroupB(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
  public ViewGroupB(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }
  
  
  

  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    
    Log.d("付勇焜----->","ViewGroupB dispatchTouchEvent");
    return super.dispatchTouchEvent(ev);
  }
  
  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    
    Log.d("付勇焜----->","ViewGroupB onInterceptTouchEvent");
    return super.onInterceptTouchEvent(ev);
  }
  
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    Log.d("付勇焜----->","ViewGroupB onTouchEvent");
    return super.onTouchEvent(event);
  }
}

然后再编写MyView,如下:

package com.example.testmotionevent;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View{

  public MyView(Context context) {
    super(context);
  }
  public MyView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
  public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }
  
  
  @Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    Log.d("付勇焜---->","MyView dispatchTouchEvent ");
    return super.dispatchTouchEvent(event);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    
    Log.d("付勇焜---->","MyView onTouchEvent ");
    return super.onTouchEvent(event);
  }
}

好了,现在就将它们嵌套在一起,修改activity_main.xml,如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  >

  <com.example.testmotionevent.ViewGroupA
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#ff0033">
    <com.example.testmotionevent.ViewGroupB
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:gravity="center"
    android:background="#336699">
     <com.example.testmotionevent.MyView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:clickable="true"
    android:background="#ffff00"/>
    
      
    </com.example.testmotionevent.ViewGroupB>
    
    
  </com.example.testmotionevent.ViewGroupA>
    

</LinearLayout>

嵌套完成,运行程序,是什么样子的呢?如下图:

红色的就是ViewGroupA,蓝色的就是ViewGroupB,黄色就是MyView。现在来点击中间黄色的MyView,观察下打印结果,如下:

从打印的结果,我们可以很清楚到看到事件的流程:

首先ViewGroupA得到了事件,由它的dispatchTouchEvent方法来分发事件,由于它的onInterceptTouchEvent方法没有做出拦截,因此事件传递给了ViewGroupB,

而同样由于ViewGroupB的onInterceptTouchEvent方法在它的dispatchTouchEvent方法分发事件时没有做出拦截,故而事件最终被传递给MyView,MyView就来处理这个事件了。

下面我们来做实验吧,我们让MyView没有处理这个事件,会是上面我们所说的由ViewGrouPB来处理吗?修改MyView的onTouchEvent事件,如下:

 public boolean onTouchEvent(MotionEvent event) {
    
    Log.d("付勇焜---->","MyView onTouchEvent ");
    return false;
//    return super.onTouchEvent(event);
  }

我们return了false,表示MyView没有成功处理这个事件。现在来再运行下程序,打印结果如下:

由于MyView的onTouchEvent返回false,因此事件就交给了它的上级ViewGroupB来处理,于是ViewGroupB的onTouchEvent就来消化这个事件了。所以

从打印的结果来看正是这个情况(即红色线条标注的部分)。但是由于ViewGroupB的onTouchEvent也没有成功处理这个事件所以又传递给ViewGroupA的

onToucEvent来处理这个事件(即红色线最下面还有ViewGroupA的标志)。不管ViewGroupA能不能成功处理,我们的程序中它是终极boss,不会再由其他对象

来处理该事件了。

再来在上一步的基础上继续做实验。当MyView没有成功处理事件,传递给ViewGroupB来处理时,当ViewGroupB处理完,我们强制告知程序,ViewGroupB

已经成功处理该事件了,看看会出现什么情况!修改ViewGroupB的onTouchEvent代码,如下:

public boolean onTouchEvent(MotionEvent event) {
    Log.d("付勇焜----->","ViewGroupB onTouchEvent");
    
    return true; //表示事件已经成功处理
//    return super.onTouchEvent(event);
  }

再来运行程序,观察打印结果如下:

观察红线部分,此时只剩下ViewGroupB的onTouchEvent了。因为ViewGroupB已经成功处理这事件了,那就不必再劳烦ViewGroupA来吃处理了。

好了,现在我们在上一个实验的基础上再来实验。比如,当事件传递到ViewGroupB的时候,ViewGroupB比较好心,心想干脆我来处理这个事情吧,就不必再让MyView

加班了,于是他对这个事件进行了拦截!修改ViewGroupB的onInterceptTouchEvent代码,如下:

@Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    
    Log.d("付勇焜----->","ViewGroupB onInterceptTouchEvent");
    return true;
//    return super.onInterceptTouchEvent(ev);
  }

再次运行程序,观察打印结果,如下:

我们发现事件传递到ViewGroupB的地方直接终止了,然后就是ViewGroupB的onTouchEvent事件来处理了,当然了因为之前我们强制修改ViewGroupB的onTouchEvent

为处理成功,因此也不会再返回给ViewGroupA的onTouchEvent来处理了。此时MyView压根就不知道有个触摸事件在它的上层传递呢!所以在打印结果中,我们连MyView的影子

都见不到!

好了,我就带大家做这几个实验吧。已经足够说明问题了。下面我们就来做一下总概述吧。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

从上面的实验我们可以很清晰的看到一个事件处理的流程,在正常情况下,是如下图的这样子的一个流程

也就是说,一个事件是必须要先经过传递流程才会再经过处理流程。这个先后顺序一定要明白。如果你无法理解,请再想一想上面拟人化的公司员工处理事件的流程吧。

其中,在红色线和蓝色线代表传递的流程中,我们都可以进行所谓的拦截事件。说明如下:

对于事件的拦截,我们主要重写就是OnInterceptTouchEvent和onTouchEvent方法。

两句就可以总结:

(1)对于事件的传递,返回结果为true,表示拦截,不再往下传递,为false,不拦截,继续往下传递。主要针对的就是OnInterceptTouchEvent方法。

(2)对于事件的处理,返回结果为true,表示拦截,不再往上传递(即我处理的很完美,不需要你再来审核我!),返回结果为false(没有成功处理事件),继续向上传递。 针对就是onTouchEvent方法。

因此我们就可以通过控制OnInterceptTouchEvent和onTouchEvent方法的返回值来控制整个事件的传递流程和处理流程!!到此,你是不是对andorid中的事件的整个处理机制很

明白了呢?以后再出现什么问题,是不是就可以顺藤摸瓜,找到问题所在了!

三、总结

如果你嫌上面的解释太啰嗦了。那么就只看下面的这个总结就可以了,一下就找到关键的知识点!如下:

(1)正常情况下,android中的事件是必须要经过传递流程然后再经过处理流程的。要记住这个先后的顺序。

(2)在传递流程和处理流程中,你都可以修改方法的返回值,来对流程做控制。

如下:

对于事件的拦截,我们主要重写就是OnInterceptTouchEvent和onTouchEvent方法。两句就可以总结:

事件的传递,返回结果为true,表示拦截,不再往下传递,为false,不拦截,继续往下传递。主要针对的就是OnInterceptTouchEvent方法。

事件的处理,返回结果为true,表示拦截,不再往上传递(即我处理的很完美,不需要你再来审核我!),返回结果为false(没有成功处理事件),继续向上传递。

针对就是onTouchEvent方法。

(3)如果流程你还理解,就好好想一想那个公司员工的拟人化解释吧!实际上android的事件处理机制原理就是这样子的!

以上这篇老生常谈android中的事件传递和处理机制就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# android事件处理机制  # 详解Android的两种事件处理机制  # Android View 事件分发机制详解  # 深入解析Android中的事件传递  # Android事件的分发机制详解  # 详细分析Android中onTouch事件传递机制  # 好了  # 这件事  # 再来  # 重写  # 就可以  # 往下  # 就不  # 你来  # 就来  # 这样子  # 会再  # 如果你  # 也有  # 你是  # 那就  # 也没  # 基础上  # 我们可以  # 给了  # 给大家 


相关文章: 宁波自助建站系统如何快速打造专业企业网站?  Python lxml的etree和ElementTree有什么区别  广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?  安云自助建站系统如何快速提升SEO排名?  如何快速查询网站的真实建站时间?  如何选择网络建站服务器?高效建站必看指南  建站主机服务器选购指南:轻量应用与VPS配置解析  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  如何用狗爹虚拟主机快速搭建网站?  公司网站的制作公司,企业网站制作基本流程有哪些?  天津个人网站制作公司,天津网约车驾驶员从业资格证官网?  建站之星如何修改网站生成路径?  打鱼网站制作软件,波克捕鱼官方号怎么注册?  网站制作企业,网站的banner和导航栏是指什么?  如何设计高效校园网站?  c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  建站之星云端配置指南:模板选择与SEO优化一键生成  网站制作价目表怎么做,珍爱网婚介费用多少?  如何快速生成可下载的建站源码工具?  如何选择适配移动端的WAP自助建站平台?  在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?  用v-html解决Vue.js渲染中html标签不被解析的问题  linux top下的 minerd 木马清除方法  装修招标网站设计制作流程,装修招标流程?  制作网站的基本流程,设计网站的软件是什么?  子杰智能建站系统|零代码开发与AI生成SEO优化指南  如何制作一个表白网站视频,关于勇敢表白的小标题?  网站制作软件免费下载安装,有哪些免费下载的软件网站?  韩国服务器如何优化跨境访问实现高效连接?  天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?  高端建站如何打造兼具美学与转化的品牌官网?  常州企业建站如何选择最佳模板?  建站之星伪静态规则如何设置?  XML的“混合内容”是什么 怎么用DTD或XSD定义  如何在建站主机中优化服务器配置?  Android自定义listview布局实现上拉加载下拉刷新功能  如何通过商城自助建站源码实现零基础高效建站?  潍坊网站制作公司有哪些,潍坊哪家招聘网站好?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  详解jQuery中基本的动画方法  建站之星如何实现PC+手机+微信网站五合一建站?  如何选择高效稳定的ISP建站解决方案?  制作证书网站有哪些,全国城建培训中心证书查询官网?  北京网站制作网页,网站升级改版需要多久?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  如何配置IIS站点权限与局域网访问?  如何基于云服务器快速搭建个人网站?  如何快速搭建虚拟主机网站?新手必看指南  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  免费制作海报的网站,哪位做平面的朋友告诉我用什么软件做海报比较好?ps还是cd还是ai这几个软件我都会些我是做网页的? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。