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

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

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


推荐阅读
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
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社区 版权所有