热门标签 | 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分发机制
横竖方向冲突  

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

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


推荐阅读
  • 基于SSM框架的在线考试系统:随机组卷功能详解
    本文深入探讨了基于SSM(Spring, Spring MVC, MyBatis)框架构建的在线考试系统中,随机组卷功能的设计与实现方法。 ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • JavaScript 跨域解决方案详解
    本文详细介绍了JavaScript在不同域之间进行数据传输或通信的技术,包括使用JSONP、修改document.domain、利用window.name以及HTML5的postMessage方法等跨域解决方案。 ... [详细]
  • 本文详细介绍如何在 Apache 中设置虚拟主机,包括基本配置和高级设置,帮助用户更好地理解和使用虚拟主机功能。 ... [详细]
  • 本文详细解析了MySQL中常见的几种错误,并提供了具体的解决方法,帮助开发者快速定位和解决问题。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
  • Android 中的布局方式之线性布局
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文深入探讨了WPF框架下的数据验证机制,包括内置验证规则的使用、自定义验证规则的实现方法、错误信息的有效展示策略以及验证时机的选择,旨在帮助开发者构建更加健壮和用户友好的应用程序。 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
  • 在尝试加载支持推送通知的iOS应用程序的Ad Hoc构建时,遇到了‘no valid aps-environment entitlement found for application’的错误提示。本文将探讨此错误的原因及多种可能的解决方案。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 2023年,Android开发前景如何?25岁还能转行吗?
    近期,关于Android开发行业的讨论在多个平台上热度不减,许多人担忧其未来发展。本文将探讨当前Android开发市场的现状、薪资水平及职业选择建议。 ... [详细]
  • 使用TabActivity实现Android顶部选项卡功能
    本文介绍如何通过继承TabActivity来创建Android应用中的顶部选项卡。通过简单的步骤,您可以轻松地添加多个选项卡,并实现基本的界面切换功能。 ... [详细]
  • 本文介绍了SIP(Session Initiation Protocol,会话发起协议)的基本概念、功能、消息格式及其实现机制。SIP是一种在IP网络上用于建立、管理和终止多媒体通信会话的应用层协议。 ... [详细]
  • 探索Java 11中的ZGC垃圾收集器
    Java 11引入了一种新的垃圾收集器——ZGC,由Oracle公司研发,旨在支持TB级别的内存容量,并保证极低的暂停时间。本文将探讨ZGC的开发背景、技术特点及其潜在的应用前景。 ... [详细]
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社区 版权所有