文章结构

=======================

###效果预览

直接上效果图图1。点击”Click Me”按钮,会弹出Toast提示”U click on the button.”;通过TouchDelegate的设定,可以将点击事件的感应区域扩大或移动至界面中的任意区域。

touch.delegate

图1. 效果图
(word无法播放gif,请双击打开preview.gif或右键“另存为”)

由效果图,可以看点击比按钮本身区域大得多的绿色区域,也可以触发按钮的点击事件。

=======================

###TouchDelegate解析

TouchDelegate能够帮助组件拥有比组件真实范围更大的点击区域,这种情况下组件被称之为委托组件(delegate view)。

由于点击/触摸事件的分发是由父组件按布局层次逐级向下匹配执行,所以设置委托组件(delegate view)的操作必须在该委托组件的父组件(parent view)。

当父组件在分发事件时,发现事件区域处于委托组件或委托组件的委托区域(delegate bound)范围内时,则将该事件分发给委托组件;也正因如此,委托区域的设置只能是在其父组件的区域范围内。如下图2。

detegate.view

图2. 委托区域位置的设置

在图2,Activity View Root是占据着整个手机屏幕,Button设置的委托区域可以是A也可以是A1,但不可能超出Button Parent View的范围。当委托区域为A1时,虽然与Button的原有范围不重合,但不会导致Button自身点击无效,仍可正常接收点击。

=======================

###TouchDelegate应用场景

在普通应用中,如图2中委托区域A的设置,这是最常用的场景,即不改变原有的组件布局或布局文件,简单设置委托区域即可调整组件的点击区域。节时省力高效。

如一个小图标被挤在一个小角落里,在不调整图标大小的情况下,设置一个大点的委托区域增加可点击的范围,就解决用户 “我点我点点不到呀”的情况。

在游戏中,设置一个如图2中委托区域A1的位置,即委托区域与委托组件不重合,那么哈哈,这是一个“彩蛋区域”呀!

TouchDelegate的代码实现
TouchDelegate的构造函数有两个参数,意义如下:

1
TouchDelegate(Rect bounds, View delegateView)

bounds:指定委托区域的范围

delegateView:需要委托的组件
设置和取消TouchDelegate的代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void enableTouchDelegate(View vDelegate, Rect rNewBounds) {
if (vDelegate == null) {
return;
}

View parent = (View) vDelegate.getParent();
if (parent == null) {
return;
}

if (rNewBounds != null) {
parent.setTouchDelegate(new TouchDelegate(rNewBounds, vDelegate));
} else {
// 取消设置点击区域代理
parent.setTouchDelegate(null);
}
}

About Sodino