触摸事件分发机制(有用的小技巧:事件二次分发)

Android 触摸事件分发和拦截机制 Android 开发中,很多情况下,我们需要对触摸事件进行处理,但是当面对错综复杂的 Android 布局时,我们如何准确的将一个用户的触摸事件传递到对应的控件中并让它进行处理呢?首先,我们先假设这里有这样一个布局:我们可以很清楚的看到,一个很明显的嵌套布局,外面两个红色的和黄色的都是布局,中间一个紫色的控件。如果此时,我们单击一下 myView 这个控件,触摸事件(单击也是触摸事件)是怎么传递的呢 阅读详情

存在的问题

在上文的下拉刷新控件中,有两个问题

  1. 在下拉到ScrollView顶部时候,继续往下拉时,并不会直接把头布局拉下来,而是需要把手松开后,再次下拉才会拉下头布局,为什么?

上文说过,onInterceptTouchEvent方法虽然不是每次都被调用,但是如果子view在处理事件的时候,onInterceptTouchEvent是一直会调用的,因为他要等待子View不想消费事件的时机出现时,交给自己处理触摸事件,按理说这个问题里,子View不想处理事件的时机已经到了,为什么父View没马上接受呢?

  1. 当刷新头已经出现了,手指上滑 ,当把刷新头完全隐藏了,继续上滑,此时由于外层布局拦截了事件,会导致把整个外层布局往上滑,而我们想要的是此时让内部的scrollview响应事件,滑动的是scrollview。

我们知道事件分发机制,一旦父view拦截了事件后,就不会把他交给子View了,所以从此之后,scrollview是不会再次有处理事件的机会的,那有什么办法,改良一下呢?

其实这些问题都指向了一个方法onInterceptTouchEvent,他的调用时机到底是什么时候。我们只看伪代码,因为伪代码是思路,是看完源码后的精华,其实这个问题在 之前博客 说过了,但是他太重要了,所以还要总结一次。

事件分发精华伪代码

先看事件分发的入口 dispatchTouchEvent伪代码:
  public boolean dispatchTouchEvent(MotionEvent ev) {
        Boolean consume = false;
        if (【当前ViewGroup要不要拦截事件(ev)】) {
        //如果本ViewGroup拦截事件,那么调用本ViewGroup的onTouchEvent
            consume = onTouchEvent(ev);
        } else {
        //否则,调用子View的dispatchTouchEvent,
        //如果子View还是一个ViewGroup的话,dispatchTouchEvent逻辑是一样的,会迭代此逻辑
        //如果子View是一个View,那他的dispatchTouchEvent是不同的(稍后给出)
            consume = child.dispatchTouchEvent(ev);
        return consume;//返回true,表示事件被消耗了,
        // 如果是最里层级的view或ViewGroup的dispatchTouchEvent返回true,表示由本ViewGroup来处理以后的事件

    }

注意【当前ViewGroup要不要拦截事件(ev)】是一个方法,方法名我写成了中文名字,这个方法内部的逻辑,才是重点。这个方法可不等同于直接调用onInterceptTouchEvent哟,而是围绕onInterceptTouchEvent展开的一系列逻辑

【当前ViewGroup要不要拦截事件(ev)】伪代码★相当重要:
public boolean 【当前ViewGroup要不要拦截事件(ev)】{
	 boolean intercepted;
	   if(DOWN事件 |或| 他的子View正在消费触摸事件) {

	        if (子View请求父容器拦截) {
		      //子View请求父容器拦截就是指,子view通过parent.requestDisallowInterceptTouchEvent(false)
		      //★★★注意只有此种情况父容器的onInterceptTouchEvent才会被调用
	  		     intercepted = onInterceptTouchEvent(ev);
	        } else {
	            //如果子View请求不拦截,那么直接返回false,根本不需要走父容器的onInterceptTouchEvent方法
	            intercepted = false; 
	                }
	    } else {
	        //当这个事件不是ACTION_DOWN,并且当前的ViewGroup也没有子ViewGroup(view)可以处理事件,那么就由本ViewGroup直接拦截这个事件,也不需要走父容器的onInterceptTouchEvent方法
	        intercepted = true;
	    }
	    return intercepted;
	}
简单说下requestDisallowInterceptTouchEvent(boolean)

注意是在子view里通过,getParent().requestDisallowInterceptTouchEvent(boolean)来使用

- requestDisallowInterceptTouchEvent(false):
子view请求拦截,让父view去询问下自己的onInterceptTouchEvent方法,看看要不要拦截

- requestDisallowInterceptTouchEvent(true):
子view请求不要拦截,那就直接返回false,不去拦截
   
总结:

关键问题在于:【当前ViewGroup要不要拦截事件(ev)】的逻辑,虽然每次触摸事件都会通过dispatchTouchEvent来调用到【当前ViewGroup要不要拦截事件(ev)】这个方法,但是这并不意味着onInterceptTouchEvent每次都会被调用。
这个关键逻辑,我们能得出以下重要结论
onInterceptTouchEvent被调用的前提条件是:

  1. Down事件&&子View请求父View不要拦截
  2. 他的子View正在消费触摸事件&&子View请求父View不要拦截

现在看看最上面抛出的问题:

  1. 在下拉到ScrollView顶部时候,继续往下拉时,并不会直接把头布局拉下来,而是需要把手松开后,再次下拉才会拉下头布局,为什么?

上文说过,onInterceptTouchEvent方法虽然不是每次都被调用,但是如果子view在处理事件的时候,onInterceptTouchEvent是一直会调用的,因为他要等待子View不想消费事件的时机出现时,交给自己处理触摸事件,按理说这个问题里,子View不想处理事件的时机已经到了,为什么父View没马上接受呢?

为什么父View没马上接受呢?因为在本例子里,内部的ScrollView在某一个时机,调用了 requestDisallowInterceptTouchEvent(false)方法,即请求父view不要拦截,那么根本不去走onInterceptTouchEvent方法,直接intercepted=false了,所以此时下拉不会落下刷新头,而是在第二次下拉时,才会访问自己的onInterceptTouchEvent,发现满足条件,就把刷新头拉下来了(此时ScrollView还没来得及调用requestDisallowInterceptTouchEvent(false)方法)

所以解决方法很简单
在父容器里重写requestDisallowInterceptTouchEvent,让

    @Override
    public void requestDisallowInterceptTouchEvent(boolean b) {
        // 去掉默认行为,使得每个事件都会经过走一下这个布局
    }

  1. 当刷新头已经出现了,手指上滑 ,当把刷新头完全隐藏了,继续上滑,此时由于外层布局拦截了事件,会导致把整个外层布局往上滑,而我们想要的是此时让内部的scrollview响应事件,滑动的是scrollview。

我们知道事件分发机制,一旦父view拦截了事件后,就不会把他交给子View了,所以从此之后,scrollview是不会再次有处理事件的机会的,那有什么办法,改良一下呢?

解决方法,就是在合适的时机,手动代码造一个Down事件,并且分发此事件,因为,这样就突破了在一系列触摸事件中,父容器拦截事件后,子View就没机会再次处理事件的问题,因为我们手动造出了第二次触摸事件,一切从Down开始

    if (mLp.topMargin <= -mHeaderHeight && deltaY <0) {
        // 重新dispatch一次down事件,使得ScrollView可以继续滚动
        int oldAction = event.getAction();
        event.setAction(MotionEvent.ACTION_DOWN);
        dispatchTouchEvent(event);
        event.setAction(oldAction);
    }

在这里插入图片描述

改良后的源码

package com.view.custom.dosometest.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ScrollView;

/**
 * 描述当前版本功能
 *
 * @Project: DoSomeTest
 * @author: cjx
 * @date: 2019-12-01 10:06  星期日
 */
public class RefreshView extends LinearLayout {


    private ScrollView mScrollView;
    private View mHeader;
    private int mHeaderHeight;
    private MarginLayoutParams mLp;

    public RefreshView(Context context) {
        super(context);
        init(context);
    }

    public RefreshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public RefreshView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }


    private void init(Context context) {
        setBackgroundColor(Color.GRAY);

        post(new Runnable() {
            @Override
            public void run() {
                initView();// 因为涉及到获取控件宽高的问题,所以写到post里
            }
        });

    }

    private void initView() {

        if (getChildCount() > 2) {

            // 给刷新头设置负高度的margin,让他隐藏
            mHeader = getChildAt(0);
            mHeaderHeight = mHeader.getMeasuredHeight();
            mLp = (MarginLayoutParams) mHeader.getLayoutParams();
            mLp.topMargin = -mHeaderHeight;
            mHeader.setLayoutParams(mLp);

            // 得到第二个view,scrollView
            View child1 = getChildAt(1);
            if (child1 instanceof ScrollView) {
                mScrollView = (ScrollView) child1;
            }

        }
    }


    float mLastY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        boolean intercept = false;
        int x = (int) ev.getX();
        int y = (int) ev.getY();

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                intercept = false;
                break;

            case MotionEvent.ACTION_MOVE:
                int deltaY = (int) (y - mLastY);
                if (needIntercept(deltaY)) {//外部拦截的模板代码,只要重写needIntercept方法逻辑就行
                    //注意当前ViewGroup一旦拦截,一次事件序列中就再也不会调用onInterceptTouchEvent了,
                    // 所以子View再也不会得到事件处理的机会了
                    // 为了解决这个问题,就引出了《嵌套滑动》这个新的事物,见下文
                    intercept = true;
                } else {
                    intercept = false;
                }

                break;

            case MotionEvent.ACTION_UP:

                intercept = false;

                break;
            default:
                break;
        }

        mLastY = y;
        return intercept;
    }

    private boolean needIntercept(int deltaInteceptY) {
        // mScrollView已经下拉到最顶部&&你还在下来,那么父容器拦截
        if (!mScrollView.canScrollVertically(-1) && deltaInteceptY > 0) {
            Log.e("ccc", "不能再往下拉了&&你还在往下拉,父布局拦截,开始拉出刷新头");
            return true;
        }
        if (mLp.topMargin>-mHeaderHeight) {
            Log.e("ccc", "只要顶部刷新头,显示着,就让父布局拦截");
            return true;
        }

        return false;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean b) {
        // 去掉默认行为,使得每个事件都会经过这个Layout
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                break;

            case MotionEvent.ACTION_MOVE:


                float deltaY = y - mLastY;

                // 防止刷新头被无限制下拉,限定个高度

                if (mLp.topMargin + deltaY > mHeaderHeight) {
                    deltaY = mHeaderHeight - mLp.topMargin;
                }
                // 动态改变刷新头的topMargin
                mLp.topMargin += (int) deltaY;
                Log.e("ccc", "y:" + y + "mLastY:" + mLastY + "deltaY:" + deltaY + "mLp.topMargin:" + mLp.topMargin);
                mHeader.setLayoutParams(mLp);

                if (mLp.topMargin <= -mHeaderHeight && deltaY <0) {
                    // 重新dispatch一次down事件,使得列表可以继续滚动
                    int oldAction = event.getAction();
                    event.setAction(MotionEvent.ACTION_DOWN);
                    dispatchTouchEvent(event);
                    event.setAction(oldAction);
                }
                break;


            case MotionEvent.ACTION_UP:
                //松手后,看位置,如果过半,刷新头全部显示,没过半,刷新头全部隐藏
                if (mLp.topMargin > -mHeaderHeight / 2) {
                    smoothChangeTopMargin(mLp.topMargin, 0);
                } else {
                    smoothChangeTopMargin(mLp.topMargin, -mHeaderHeight);
                }

                break;
        }

        mLastY = y;

        return true;
    }

    /**
     * 使用属性动画平滑地过度topMargin
     *
     * @param start
     * @param end
     */
    private void smoothChangeTopMargin(int start, int end) {
        ValueAnimator valueAnimator = ValueAnimator.ofInt(start, end);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mLp.topMargin = (int) animation.getAnimatedValue();
                mHeader.setLayoutParams(mLp);

            }
        });
        valueAnimator.setDuration(300);
        valueAnimator.start();

    }
}

cocos2d-x 事件分发机制 ——触摸事件监听 cocos2d-x 3.0 出来已经好久了,也已经用3.0写了几个小游戏,感觉3.0的事件触发机制太赞了,随这里总结一下,也算是对知识的一种回忆和加深理解。 3.0的事件分发机制中,需要也仅仅需要通过创建一个事件监听器来实现各种触发后的逻辑,然后添加到事件分发器_eventDispatcher,所有的事件监听器由这个分发器统一管理,即可完成事件响应。 事件监听器有以下几种: 1、EventL 阅读详情

相关推荐

Android事件分发机制_activity 事件分发

因为在屏幕上,是分层的,比如是现有窗口,然后有交互界面(Activity),界面中有布局(ViewGroup),布局中有控件(View)。那么如何确定到底该哪个控件来响应处理触摸事件呢,这就要用到事件分发机制了。一般来说,事件传递的顺序是:Activity -> ViewGroup -> View。1个点击事件发生后,事件先传到Activity、再传到ViewGroup、最终再传到 View。

878

短时间内防止多次点击

【代码】短时间内防止多次点击。

shuangrenlong的博客 231

【鸿蒙南向开发】触摸事件及分发机制详解

多模输入标准系统组件提供传统的输入交互方式,例如按键、触控、键盘、鼠标等。 本应用于标准系统之上,为设备提供单指触控输入能力。本组件将触屏输入产生的事件上报到 JS UI 框架或用户程序框架,JS UI 框架根据上报的事件再次封装,对应用提供接口。

HarmonyOS_666的博客 1275

Android事件传递机制:dispatchTouchEvent源码解析附具体示例

**注意:因为是解析源码,所以本文要求对Android的事件传递机制有一定的的了解。**当然我也会简单的对事件传递的知识进行提要: 一、 简单提要 同一个事件序列:指的是从手指接触屏幕的那一刻起,到手指离开屏幕的那一刻结束,在这个过程中所产生的一系列事件,这个事件以down事件开始,中间含有数量不定的move事件,最终以up事件结束。 点击事件的事件分发,就是对同一事件序列的分发,这个过程由三个很重要的方法来完成:dispatchTouchEvent,onInterceptTouchEvent,onTou

weixin_43864176的博客 6271

网络系统实现技术之IPX与SPX

IPX/SPXNovell NetWare网络Novell公司为适应网络发展,将主机网络转换为PC网络,开发了Novell NetWare网络系统。该系统中基于客户机/服务器模式。以普通PC机做为客户机,以性能强大的服务器做为服务器,为客户机提供文件服务、数据库服务及其他服务。与前面的SNA模型一样,Novell NetWare也早于OSI模型,所以不能与OSI模型严格对应,但也有很明

成片的大树 9164

Python离线断网情况下安装numpy、pandas和matplotlib等常用第三方包

联网情况下在命令终端CMD中输入“pip install numpy”即可自动安装,pandas和matplotlib同理一样方法进行自动安装。 工作的电脑不能上外网,所以不能通过直接输入pip命令来安装。 环境:电脑上已经安装了Python(没有安装的请参考其他教程)。 Python离线断网情况下安装numpy、pandas和matplotlib等常用第三方包的步骤如下: ...

dayou7738的博客 4944

Android进阶——Android事件分发机制之dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent

Android事件分发机制可以说是我们Android工程师面试题中的必考题,弄懂它的原理是我们避不开的任务,所以长痛不如短痛,花点时间干掉他,废话不多说,开车啦Android事件分发机制的发生在View与View之间或者ViewGroup与View之间具有镶嵌的视图上,而且视图上必须为点击可用。当一个点击事件产生后,它的传递过程遵循如下顺序:Activity->Window->View,即事件先传递给Activity,再到Window,再到顶级View,才开始我们的事件分发。...

点击置顶文章查看博客目录(全站式导航) 1万+

单精度浮点数存储、双精度浮点数存储

单精度浮点数存储、双精度浮点数存储

fancynthia的博客 1320

onTouch、onkey、dispatchTouchEvent、dispatchKeyEvent等方法被执行 “两次” 的解决方法

不管点击还是触屏都有按下弹起这两个事件的,onTouch会捕获ACTION_DOWN和ACTION_UP这两个动作,所以执行了两次。同理:onkey、dispatchTouchEvent、dispatchKeyEvent。要想执行一次,可加判断ACTION_DOWN和ACTION_UP这两个动作.   例1: public boolean onTouch(View v, MotionEven

xzhjsj2012的专栏 3108

Navicat16/17数据库密码安全解析与实战解密指南

本文详细解析了Navicat 16/17版本中数据库密码的加密机制,并提供了实用的密码找回指南。通过导出连接文件获取加密密文,利用基于AES-128-CBC算法的本地HTML工具,可安全、离线地解密遗忘的密码。文章强调该方法仅适用于合法恢复自有密码,并给出了操作步骤与安全建议。

weixin_28835583的博客 468

VMware Workstation Pro 16 安装 Ubuntu 20.04

VMware Workstation Pro 16 安装 ubuntu 20.04目录环境VMware Workstation下载Ubuntu 20.04下载安装过程 目录 环境 Windows 10 Workstation 16 Pro for Windows Ubuntu 20.04 LTS 64位 desktop版本 VMware Workstation下载 链接: https://www.vmware.com/products/workstation-pro/workstation-pro-eval

qq_45642410的博客 1万+

Android 事件分发onInterceptTouchEvent和onTouchEvent整理

文/milter(简书作者) 原文链接:http://www.jianshu.com/p/2be492c1df96 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。我们只考虑最重要的四个触摸事件,即:DOWN,MOVE,UP和CANCEL。一个手势(gesture)是一个事件列,以一个DOWN事件开始(当用户触摸屏幕时产生),后跟0个或多个MOVE事件(当用户四处移动手指时产生),

weiweixiaoaa的博客 643

Cadence PSpice 模型1:基于自带库新建二极管的PSpice模型图文教程

使用Cadence PSpice进行电路图的仿真时,难免会遇到软件自带库中没有合适的元器件的情况,这就需要设计师自己新建元器件模型,本文详细介绍使用PSpice软件修改自带库的元器件模型的参数以得到自己需要的PSpice模型库的方法。

fydar的博客 4413

Android触摸事件分发机制详解

触摸事件分发机制一直以来都是Android中比较重要的一大块,自定义view,各种复杂的自定义手势交互都与触摸事件分发机制关系密切,想要做好这些,就要对触摸事件了解透彻,并且需要不断的去实践来加深印象,否则在自己去实现的时候就会茫然不知所措,同时这个知识点也是面试必问的经典题目,所以说掌握它是必须的,今天就来详细分析一下整个触摸事件的分发流程和相关知识。(本文理论知识较多,比较枯燥,需要极大耐心观看~)

Water的博客 4987

华为OD机试真题2025双机位B卷 Java&Go 实现【朋友圈个数】

给定一组朋友关系,统计一下该朋友关系网中的朋友圈个数。 朋友圈的定义:一个朋友圈至少由3个朋友组成,且要求同一个朋友圈中的任意两个人都具有直接的朋友关系。 输入描述 输入一个朋友关系列表,如 Fiends =A.B],[A.C],IB,DI,其中的每一个元素 Friendsi表示 Friends[i][0)和 Friends [i][1] 是朋友关系 先输入一个数字 N 代表关系的总数,后面每条关系一行,两个成员以逗号分隔

MISAYAONE的博客 520

【OpenClaw从入门到精通】第41篇:2026年4月最新版——从零开始搭建你的第一个安全AI助理(保姆级实战教程)

2026年3月CNCERT联合发布《OpenClaw安全使用实践指南》后,安全部署成为OpenClaw使用的核心前提。本文针对新手及进阶用户,基于官方安全指引,提供三套实战部署方案:阿里云一键部署(新手首选)、Docker容器隔离部署(进阶推荐)、本地安全安装(测试专用),并详解阿里云百炼Coding Plan API接入流程。全文涵盖环境准备、分步实操、安全加固、问题排查等全流程,所有命令可直接复制执行,无需依赖外部代码库。通过本文,读者可零基础搭建安全隔离的OpenClaw AI助理,兼顾实用性与安全性

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2204

安卓触摸事件分发机制分析

🎯 一句话总结:触摸事件(TouchEvent)会从Activity层开始,按从外到内的方式传递给每一个 ViewGroup/View,直到某个 View消费(consume)它,事件传递就会停止。📌 事件分发三个关键方法方法名所在类作用说明所有 View/ViewGroup事件分发入口,决定是否继续向下传递仅 ViewGroup是否拦截事件,阻止传递给子 View所有 View/ViewGroup事件的最终处理者(消费者)DecorView是一个应用窗口的根容器,它本质上是一个。

WriteBug001的博客 972

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Android事件分发机制详解与实战剖析,一张事件分发流程图,让你彻底搞明白

本文为自己多年来在Android实战开发过程中总结归纳的一些常见问题,现在分享出来希望对初学者有所帮助。 本文出自门心叼龙的博客,转载请注明出处:https://blog.youkuaiyun.com/geduo_83/article/details/86560896 事件分发是Android开发过程中的重点又是难点,一张事件分发流程图,让你彻底搞明白。网上有很多文章写事件分发,感觉都没...

门心叼龙的专栏 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【Android】事件分发机制

从上表可以看到 Activity和 View都是没有事件拦截的,这是因为:Activity 作为原始的事件分发者,如果 Activity 拦截了事件会导致整个屏幕都无法响应事件,这肯定不是我们想要的效果。View作为事件传递的最末端,要么消费掉事件,要么不处理进行回传,根本没必要进行事件拦截。

2303_79296612的博客 1727

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

触摸事件分发机制

触摸事件分发这是我之前写的一篇事件分发的博客,这篇文章是在看了《Android开发艺术探索》后写的,书中已经给出了【外部拦截法】和【内部拦截法】的模板代码,我们可以直接拿来使用即可,书中也给出了看源码后的重要结论,博客里我写了个demo,以打印log的方式验证了一遍,帮助理解了一遍事件分发的流程。更加详细内容可参考触摸事件分发。 本篇博客贴出【外部拦截法】和【内部拦截法】代码,供大家上手使用,然后...

Android_Study_OK的博客 597

Android6.0触摸事件分发机制解读

本篇博文是Android触摸事件分发机制系列博文的第一篇,带领大家从全局掌握Android触摸事件分发机制。特别声明的是,本源码解读是基于最新的Android6.0版本。为什么要解读触摸事件分发机制1.掌握View事件分发机制 2.为解决View滑动冲突提供理论支持 3.了解Android最新源码改动Touch触摸事件    在Android中Touch触摸事件主要包括点击(onClick)

Android研发专栏 1万+

Android 触摸事件分发机制

如果该方法没有被覆写或调用了super的同名方法,则会调用 onInterceptTouchEvent 方法,如果该方法返回TRUE拦截事件,则交给自身的onTouchEvent 处理,如果该方法返回FALSE不拦截,则继续传给子子View(图中是View)的 dispatchTouchEvent方法处理。一般情况下,默认为FALSE。(1)如果经过子 View 层层传递或处理后,该事件被消费了(即返回了 TRUE),则 Activity 的分发方法也返回 TRUE,同样也表示该事件已经被消费了。

m0_61945436的博客 732

触摸事件的分发机制

ViewGroup的事件分发机制View一般都包含在ViewGroup中,例如在actingity中触摸事件一般从window、activity、decorView、ViewGroup,最后才是被点击的空间,所以其中的触摸事件分发机制就必须搞清楚。ViewGroup的触摸事件分发方法 dispatchTouchEvent 事件分发 InterceptTouchEvent 事件拦截

didiaodazhong的博客 412

Android触摸事件分发机制

Android 中的事件分为按键事件和触摸事件,这里我们对触摸事件进行阐述。 Touch 事件是由一个 ACTION_DOWN,n个 ACTION_MOVE,一个 ACTION_UP 组成 onClick,onLongClick,onScroll 等事件。 Android 中的控件都是继承 View 这个基类的,而控件分为两种:一种是继承 View 不能包含其他控件的控件;一种是继承 Vi

mjd的专栏 1087

Android触摸反馈(回顾整理):触摸事件的分发机制、拦截机制。

Android触摸反馈:触摸事件的分发机制、拦截机制。

手写我对你的温柔 3568
上一篇: 触摸事件分发机制
下一篇: 多点触摸处理
Android_Study_OK
博客等级 码龄11年 91粉丝 128原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值