| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android事件分发机制四:学了事件分发有什么用?,推荐 -> 正文阅读 |
|
[移动开发]Android事件分发机制四:学了事件分发有什么用?,推荐 |
那么关于事件分发的知识在上面三篇文章也就分析地差不多了,接下来就分析一下学了之后该如何使运用到实际开发中,简单阐述一下笔者的思考。 Android中的view一般由两个重要的部分组成:绘制和触摸反馈。如何精准地针对用户的操作给出正确的反馈,是我们学事件分发最重要的目标。 运用事件分发一般有两个场景:给view设置监听器和自定义view。接下来就针对这两方面展开分析,最后再给出笔者的一些思考与总结。 监听器 触摸事件监听器可以说是我们接触Android事件体系的第一步。监听器通常有:
这些是我们使用得最频繁的监听器,他们之间的关系是:
上面的伪代码可以很明显地发现:onTouchListener是直接把MotionEvent对象直接接管给自己处理且会最先调用,而其他的两个监听器是view判断点击类型之后再分别调用?。 除此之外,另一个很常见的监听器是双击监听器,但这种监听器并不是view默认支持的,需要我们自己去实现。双击监听器的实现思路可以参考view实现长按监听器的思路来实现:
我们可以实现?
代码中实现了创建了一个?
这样就实现了按钮的双击监听了。 其他类型的监听器如:三击、双击长按等等,都可以基于这种思路来实现监听器接口。 自定义view 在自定义view中,我们可以更加灵活地运用事件分发来解决实际的需求。举几个例子: 滑动嵌套问题:外层是viewPager,里层是recyclerView,要实现左右滑动切换viewPager,上下滑动recyclerView。这也就是著名的滑动冲突问题。类似的还有外层viewPager,里层也是可以左右滑动的recyclerView。 实时触摸反馈问题:如设计一个按钮,要让他按下的时候缩小降低高度,放开的时候恢复到原来的大小和高度,而且如果在一个可滑动的容器中,按下之后滑动不会触发点击事件而是把事件交给外层可滑动容器。 我们可以发现,基本上都是基于实际的开发需求来灵活运用事件分发。具体到代码实现,都是围绕着三个关键方法展开:? 实现方块按下缩小 我们先来看看具体的实现效果: 方块按下后,会缩小高度变低透明度增加,释放又会恢复。 这个需求可以通过结合属性动画来实现。按钮块本身有高度、有圆角,我们可以考虑继承cardView来实现,重写cardView的dispatchTouchEvent方法,在按下的时候,也就是接收到down事件的时候缩小,在接收到up和cancel事件的时候恢复。注意,这里可能会忽视cancel事件,导致按钮块的状态无法恢复,一定要加以考虑cancel事件?。然后来看下代码实现:
动画方面的内容就不分析了,不属于本文的范畴。可以看到我们只是给cardView设置了动画效果,监听事件我们可以设置给cardView内部的ImageView或者直接设置给CardView。需要注意的是,如果设置给cardView需要重写cardView的? 解决滑动冲突 滑动冲突是事件分发运用最频繁的场景,也是一个重难点(敲黑板,考试要考的)。滑动冲突的基本场景有以下三种:
解决这类问题一般有两个步骤:确定最终实现效果、代码实现。 滑动冲突的解决需要结合具体的实现需求,而不是一套解决方案可以解决一切的滑动冲突问题,这不现实。因此在解决这类问题时,需要先确定好最终的实现效果,然后再根据这个效果去思考代码实现。这里主要讨论情况一和情况二,情况三类同。 情况一 情况一是内外滑动方向不一致。这种情况的通用解决方案就是:根据手指滑动直线与水平线的角度来判断是左右滑动还是上下滑动: 如果这个角度小于45度,可以认为是在左右滑动,如果大于45度,则认为是上下滑动。那么现在确定好解决方案,接下来就思考如何代码实现。 滑动角度可以通过两个连续的MotionEvent对象的坐标计算出来,之后我们再根据角度的情况选择把事件交给外部容器还是内部view。这里根据事件处理的位置可分为内部拦截法和外部拦截法?。
从实现的复杂度来看,外部拦截法会更加优秀,不需要里外view去配合,只需要viewGroup自身做好事件拦截处理即可。两者的区别就在于主动权在谁的手上。如果view需要做更多的判断可以采用内部拦截法,而一般情况下采用外部拦截法会更加简单。 接下来思考一下这两种方法的代码实现。 外部拦截法中,重点在于是否拦截事件,那么我们的重心就放在了?
代码的实现思路很简单,记录两次触控点的位置,然后计算出斜率来判断是垂直还是水平滑动。代码中有个需要注意的点:viewGroup不能拦截up事件和down事件。如果拦截了down事件那么子view将永远接收不到事件信息;如果拦截了up事件那么子view将永远无法触发点击事件。 上面的代码是事件分发的核心代码,更加具体的代码还需要根据实际需求去完善细节,但整体的逻辑是不变的。 内部拦截法的思路和外部拦截的思路很像,只是判断的位置放到了内部view中。内部拦截法意味着内部view必须要有控制事件流走向的能力,才能对事件进行处理。这里就运用到了内部view一个重要的方法:? 这个方法可以强制外层viewGroup不拦截事件。因此,我们可以让viewGroup默认拦截除了down事件以外的所有事件。当子view需要处理事件时,只需要调用此方法即可获取事件;而当想要把事件交给viewGroup处理时,那么只需要取消这个标志,外层viewGroup就会拦截所有事件。从而达到内部view控制事件流走向的目的。 代码实现需要分两步走,首先是设置外部viewGroup拦截除了down事件以外的所有事件(这里用viewPager和ListView来进行代码演示):
接下来需要重写内部view的dispatchTouchEvent方法:
两种方法的代码思路基本一致,但是内部拦截法会更加复杂一点,所以在一般的情况下,还是使用外部拦截法较好。 到这里已经解决了情况一的滑动冲突解决方案,接下来看看情况二的滑动冲突如何解决。 情况二 第二种情况是里外容器的滑动方向是一致的,这种情况的主流解决方法有两种,一种是外容器先滑动,外容器滑动到边界之后再滑动内部view,例如京东app(注意向下滑动时的情况): 第二种情况的内部view先滑动,等内部view滑动到边界之后再滑动外部viewGroup,例如饿了么app(注意向下滑动时的情况): 最后愿你有一天,真爱自己,善待自己。
|
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:44:15- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |