TouchDelegate的这些盲区了解一下?

简介: TouchDelegate的这些盲区了解一下?

1. 前言


早些时候我发了一篇关于对话框动画的文章全网独一份的对话框弹出样式。用户阅读量,分享量,阅读后关注量等数据比较好。与之前偏重Android源码解析的文章不同,那是一篇更偏实战的文章。美中不足的是,代码注释量很少,有读者反馈阅读体验不佳。如果这个问题也曾困扰过你,借此向您真诚道歉,由于行文仓促,没有投入更多精力,今后在文章润色上投入更多时间,争取为读者带来更好的阅读体验。

如果您觉得我的文章写的还行,帮我点个在看,或者分享出去,您的支持是我最大的动力。如果您有好的建议,欢迎您在留言区留言。

2. 关于TouchDelegate


本文内容不仅限于TouchDelegate的简单使用,也会涉及到原理讲解,它的局限性以及解决方案。

工作中,可能会遇到这种情况

设计师:"呀,你这个按钮点击太不灵敏了,能不能把点击区域放大一点?"

开发:"我这个按钮大小,跟你设计稿上标注的一样大呀!要不然你把图片切大一点?"

修改按钮大小,当然可以扩大按钮的点击区域,在不修改按钮大小的前提下,能否做到扩大按钮的点击区域呢?

当然可以,用TouchDelegate就能做到。

2.1 核心方法


  1. TouchDelegate(Rect bounds, View delegateView)

640.png

View delegateView:指需要扩大点击区域的控件。


Rect bounds:指delegateView响应事件的区域,一般比它的原始范围要大。


  1. View#setTouchDelegate(TouchDelegate delegate)

640.png

TouchDelegate是View.java的成员变量。View对象一般是delegateView的祖先控件(不仅仅是父控件,可以是祖先控件)


2.2 场景


场景一:父控件区域足够大,扩大单个Button点击范围


如下图,将Button的点击区域扩大500像素

640.png


代码如下

640.png

「这样设置,那么在绿色区域内点击,Button按钮同样能够响应到点击事件。

640.png


场景二:父控件区域很小,扩大单个Button点击范围


粉红色ViewGroup区域只比Button大一点,将Button点击区域扩大500像素。

640.png


如果调用ViewGroup.setTouchDelegate()则没效果,需要调用Root.setTouchDelegate()。

640.png


「某ViewGroup想扩大它的后代View的点击区域,必须保证ViewGroup有足够的空间,否则寻找空间足够大的祖先控件来扩大后代View的点击区域」


场景三:同时有多个Button想扩大点击区域


如下图,同时扩大Button1、Button2的点击区域500像素

640.png


「也许你可能会说,这还不简单吗?我信手拈来,写下如下代码」


640.png

「但是很不幸运,只有button2的点击区域扩大了500像素,button1的点击区域并没有扩大,这是系统默认的TouchDelegate的局限性,只能给一个后代View扩大点击区域,后面我将给出解决方案」


场景四:扩大点击区域的Button周围填充了其它View

640.png

伪代码如下,假设left、top等View的宽高刚好是500像素

640.png


「当用户点击在left、top等View上,即使已经将Button1的点击扩大了500px,Button1也无法获取点击事件。因为只有当ViewGroup的所有子View都不处理事件,才会轮到TouchDelegate去分发事件。这涉及到事件分发机制具体请参考 深度遍历讲解Android事件分发机制


3. 原理分析


3.1 核心方法

  1. View.onTouchEvent(MotionEvent event)
  • 如果设置了TouchDelegate,则调用它的onTouchEvent,如果返回true,调用结束,否则往下走
  • 处理OnClickListener,OnLongClickListener等事件

640.png


  1. TouchDelegate.onTouchEvent(MotionEvent event)
  • Down事件,判断手指是否落在事件扩大范围内
  • 非Down事件,判断手指是否超出了slopBounds,slopBounds是在bounds的区域上再扩大一定的范围,如果超出,向delegateView发送一个负值事件坐标
  • 如果分发事件,将事件坐标设置为delegateView的中心点
  • 如果手指超出了最大范围,将事件坐标设置为负值分发


640.png


4. DEMO代码


demo已上传至https://github.com/lizijin/zijiexiaozhan。由于国内网络环境问题,有可能需要自备梯子访问。如果您无法获取代码,请私信我。

运行截图如下

640.png

5. 突破局限


场景三:同时有多个Button想扩大点击区域,我们讲到,系统的TouchDelegate无法同时给多个View设置扩大点击区域。

假设有如下需求,想同时扩大加购和减购的点击区域,该如何做呢?

640.jpg

最终效果如下。如图,点击在加减购周围,同样能够触发事件。

640.gif


核心代码,重写TouchDelegate。

640.png

完整代码已上传至https://github.com/lizijin/zijiexiaozhan。由于国内网络环境问题,有可能需要自备梯子访问。如果您无法获取代码,请私信我。


6. 总结


  1. 盲区一:设置TouchDelegate,必须在需要扩大点击区域的View的祖先View上。
  2. 盲区二:如果祖先View空间,比子View需要的区域还小,无法正确扩大点击区域。
  3. 盲区三:如果View周边有其它的View消耗事件,那么扩大点击区域可能无效。
  4. 盲区四:系统默认情况,无法给多个View扩大点击区域。

最后:码字不易。帮忙点个在看,或者分享给朋友。感激涕零。

相关文章
|
存储 编译器 程序员
2022的愿望:反抗C字辈的打压。(2)
2022的愿望:反抗C字辈的打压。(2)
2022的愿望:反抗C字辈的打压。(2)
|
存储 JavaScript 前端开发
2022的愿望:反抗C字辈的打压。(3)
2022的愿望:反抗C字辈的打压。(3)
2022的愿望:反抗C字辈的打压。(3)
|
存储 JavaScript Java
2022的愿望:反抗C字辈的打压。(1)
2022的愿望:反抗C字辈的打压。(1)
2022的愿望:反抗C字辈的打压。(1)
|
运维 安全 Cloud Native
潜伏的怪兽:研发过程中的安全风险|学习笔记
快速学习潜伏的怪兽:研发过程中的安全风险
210 0
潜伏的怪兽:研发过程中的安全风险|学习笔记
|
运维 安全 Cloud Native
潜伏的怪兽:研发过程中的安全风险 | 学习笔记
快速学习潜伏的怪兽:研发过程中的安全风险
潜伏的怪兽:研发过程中的安全风险 | 学习笔记
|
人工智能 物联网 编译器
中科院计算所对「木兰」问题进行处理:当事人停职,将深入调查
国产编程语言「木兰」在推出之后受到了人们的质疑。昨天下午,中国科学院计算技术研究所对此进行了回应。
179 0
中科院计算所对「木兰」问题进行处理:当事人停职,将深入调查
幼儿园食品安全舆情工作怎么做?
一直以来食品安全问题就是全民关注的焦点,再加上幼儿园作为这一特殊主体,尤其是近年来有关幼儿园食品安全问题的报道层出不穷,如涉及到的食堂餐具安全问题、食材安全问题、食堂工作人员卫生安全问题等等。
宁国:在疫情防控一线采取十项措施 加强干部考察识别和选拔使用
当前,全国上下正处于新型冠状病毒感染的肺炎疫情防控阻击战的关键时期。越是重要关头和关键时刻,越能锻炼干部、考验干部,也越能识别干部。为认真落实省委组织部《关于为打赢疫情防控阻击战提供坚强组织保证的通知》精神,近日,宁国市出台《关于在疫情防控一线加强干部考察识别和选拔使用的十项措施》,采取“三到位三询问”方式,重点考察“六个怎么样”,不断激励引导广大干部在疫情防控斗争中挺身而出、英勇奋斗、扎实工作,全力打赢疫情防控阻击战。
962 0
|
人工智能 机器人 区块链
相信我,我们离成为废物阶级不远了!
凯文•凯利:人工智能时代你能做啥工作? 凯文·凯利(KK)《连线》(Wired)杂志创始主编。著有《失控》、《科技想要什么》、《技术元素》、《必然》。
1129 0

相关实验场景

更多