热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidView分发机制

一、介绍  什么是分发机制?    首先了解下什么是分发机制,分发机制顾名思义,用来实现分配的功能,好比一个公司领导下发任务给部门领
一、介绍

    什么是分发机制?

    首先了解下什么是分发机制,分发机制顾名思义,用来实现分配的功能,好比一个公司领导下发任务给部门领导,部门领导下发任务给员工。

    View分发机制的作用

    分发机制在view中起到什么作用呢,和上面举例类似,它的作用是用来分发view的点击事件,我们常遇到的如滑动冲突问题,就是典型的分发机制的一个难点,分发机制说起来难其实也不难,说简单也不简单,下面会一一介绍.

二、分发机制的传递规则    

    首先了解规则之前我们先了解几个关键对象

    1.MotionEvent

      这个应该都不陌生,点击事件的对象,从这个对象中可以获取到我的点击事件当前的状态,像MotionEvent.ACTION_UP、MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE,在事件分发中也是必不可少的一个对象.

    2. 事件分发几个关键方法

        ①dispatchTouchEvent()–>分工

                此方法作用在于分发任务,一个view执行分发之前首先会执行此方法,用来分发任务,我们可以理解为领导管理者,领导向下分发任务,起到一个管理分工作用.                

        ②onInterceptTouchEvent()–>拦截

                此方法作用在于拦截事件,当领导层也就是dispatchTouchEvent方法下发了分发任务,如果需要执行此任务就需要此方法告知我们的领导层(dispatchTouchEvent),我要接受这个任务,起到一个拦截任务的作用,如果不拦截则会由其他下级view处理是否拦截.

        ③onTouchEvent()–>处理

                  此方法作用在于处理事件,当我们拦截了分发的事件任务的时候,我们需要用到此方法来处理这次分发的任务,如果此方法不处理,则分发给下一级view去处理,例如我们接受了领导下发的任务,也成功拦截接受了任务,在处理的时候我们发现我们处理不了次任务或者不想处理,这时候就需要给其他员工去处理 (子view).

    3.分发规则

        想了解分发的传递规则首先我们一起看下这段伪代码,能更好理解.

        public boolean dispatchTouchEvent(MotionEvent ev){

            boolean cOnsume= false;

            if(onInterceptTouchEvent(ev)){

                    cOnsume= onTouchEvent(ev);

            }else{

                    cOnsume= child.dispatchTouchEvent(ev);

            }

            return consume;

        }

        由上代码可以很清楚的看出,分发的传递规则,首先dispatchTouchEvent归属于顶层view,默认consume返回false也就是不处理此次事件,但是我们看到onInterceptTouchEvent方法如果返回true,也就是说我们拦截了事件,这个时候会走此view的onTouchEvent方法,当onTouchEvent方法返回true的时候代表此次事件我们这个顶层view处理了,其他view无需处理此事件,如果onTouchEvent返回false代表我们处理不了或者不处理此次事件,则dispatchTouchEvent直接返回false,如果我们不拦截此次事件的话也就是onInterceptTouchEvent返回false,我们可以看到else中有这样的代码 child.dispatchTouchEvent(ev);,child顾名思义代表子view,也就是说我们onInterceptTouchEvent返回false(不拦截此次事件的话),我们交由下一个子view进行处理,子view也按照这样的逻辑依次传递下去.

        分发顺序

             一般分发顺序由Activity->Window->View(开始分发)->子view

             上提到了分发规则,但是如果所有的view都不处理此次事件,那会如何呢?

              如果所有view都不处理的话,事件会传递给Activity处理.

        点击事件优先级

                点击事件一般会走如下方法:

                 OnTouch(也就是OnTouchListener)  > OnTouchEvent  >  OnClick.

                  由上可以看出点击事件的优先级, 当view处理点击事件时,首先会判断是否设置了OnTouchListener如果设置了那么OnTouch方法将被调用, 这时是否交由OnTouch方法还需要确认它的返回值, 如果返回false,则OnTouchEvent方法将被执行, 如果是true, OnTouchEvent不会被调用, 如果OnTouchEvent中,设置了OnClick则OnClick会被调用,也就是OnClick处理的优先级最低.

        3.滑动冲突

                  提到分发机制必不可少的就是滑动冲突这类问题,也是分发机制涉及的主要普遍疑难问题之一.

                  要解决这类问题我们首先了解下事件序列, 从手势按下也就是DOWN,到MOVE,最后手势抬起UP,这期间也就是分发事件过程,称之为一个事件序列.

                  那我们解决滑动冲突也就是说在这个事件序列中解决事件分发问题,也就是一个事件中特定的情况下(比如我向上滑动) 将这个向上滑动的操作,分发给哪个View去处理,这也是解决滑动冲突的原理.                    

                   第一种也就是2个同方向View的滑动冲突, 这类问题比较复杂, 想要解决需要配合实际的业务场景, 因为是同方向我们无法通过角度,滑动方向等来判断,需要分发给哪个view执行,这次事件序列, 因此我们就需要一些附加条件来作为我们判断的条件,比如当内部view在什么状态的情况下我分发给它此次事件序列,当外部view在另一个状态下分发给外部此次事件序列.

Android-View分发机制
同方向冲突

                    第二种也就是横竖两个方向View的滑动冲突, 这类问题算是相对比较好解决,一般viewpager会自动处理这类问题,如果外部使用viewpager的小伙伴不需要考虑冲突的问题,如果其他情况,则就需要用到分发机制来处理.

                     ① 外部拦截: 我们可以在外部view拦截,也就是使用拦截方法onInterceptTouchEvent,在此方法中判断我们的条件,可以根据滑动距离判断滑动方向以及角度,由此判断我们拦截方法是否返回true, 如果符合条件返回true,代表我们拦截了此方法,此时外部滑动生效, 如果返回false, 则不符合条件,交由内部view也就是子view处理。

                   ② 内部拦截: 内部拦截也就是外部不处理任何事件,在内部进行同样的条件判断是否拦截,如果内部拦截成功,则内部滑动生效,如果拦截失败也就是返回false,则交由上级view处理, 这里是反向分发可以理解为 ,不符合我们的分发机制,交由上层view处理的话这里需要用到parent.requestDisalLowInterCeptTouchEvent(false), 此方法作用也就是子view调用如下方法时,父view会继续拦截本次事件序列.

Android-View分发机制
横竖方向冲突  

            滑动冲突举例就这两种了目前,其他情况下可更加更复杂的情况判断分发事件.

 本文就到这里,如有错误请指正.


推荐阅读
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 本文详细介绍 Go+ 编程语言中的上下文处理机制,涵盖其基本概念、关键方法及应用场景。Go+ 是一门结合了 Go 的高效工程开发特性和 Python 数据科学功能的编程语言。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 解决PHP与MySQL连接时出现500错误的方法
    本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • Yii 实现阿里云短信发送 ... [详细]
author-avatar
手机用户2602936393
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有