Android 避坑指南:TouchDelegate的这些盲区了解一下?扩展点击区域

避坑系列其他文章:

Android 避坑指南:实际经历来说说IdleHandler的坑

Android 避坑指南:Gson 又搞了个坑!

Android避坑指南,发现了一个极度不安全的操作

1

关于TouchDelegate

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

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

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

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

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


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

1.1 核心方法

1、TouchDelegate(Rect bounds, View delegateView)

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

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

2、View#setTouchDelegate(TouchDelegate delegate)

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

1.2 场景

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

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

代码如下

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

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

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

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

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

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

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

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

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

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

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

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

2

原理分析

2.1 核心方法

1、View.onTouchEvent(MotionEvent event)

  • 如果设置了TouchDelegate,则调用它的onTouchEvent,如果返回true,调用结束,否则往下走

  • 处理OnClickListener,OnLongClickListener等事件

    2、TouchDelegate.onTouchEvent(MotionEvent event)

  • Down事件,判断手指是否落在事件扩大范围内。

  • 非Down事件,判断手指是否超出了slopBounds,slopBounds是在bounds的区域上再扩大一定的范围,如果超出,向delegateView发送一个负值事件坐标。

  • 如果分发事件,将事件坐标设置为delegateView的中心点。

  • 如果手指超出了最大范围,将事件坐标设置为负值分发。

3

DEMO代码

demo已上传至

https://github.com/lizijin/zijiexiaozhan

运行截图如下

4

突破局限

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

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

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

核心代码,重写TouchDelegate。

完整代码已上传至

https://github.com/lizijin/zijiexiaozhan

5

总结

1、盲区一:设置TouchDelegate,必须在需要扩大点击区域的View的祖先View上。

2、盲区二:如果祖先View空间,比子View需要的区域还小,无法正确扩大点击区域。

3、盲区三:如果View周边有其它的View消耗事件,那么扩大点击区域可能无效。

4、盲区四:系统默认情况,无法给多个View扩大点击区域。

转自:Android 避坑指南:TouchDelegate的这些盲区了解一下?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值