文章目录
近期在学习Android的事件点击中发现了TouchDelegate,字面意思是"触摸委托",在进一步的了解中,发现在你想要扩大View的点击范围,但是不能改变布局的时候还是比较实用的。
如何使用
首先,来看下如何使用TouchDelegate。
如果你希望将子View的点击范围扩大到父View范围,你就可以使用TouchDelegate来做到。先看下示意图:
如图所示,子View的点击范围就是子View本身,但是我想要扩展点击事件到父View的范围,也就是蓝色的范围。那么我们就可以使用TouchDelegate。
代码:
/**
* 扩大View的触摸和点击响应范围,最大不超过其父View范围
* 若想在一个父布局扩大多个View的点击区域,可以在view嵌套一个RelativeLayout或LinearLayout布局,这样就一个父布局对应一个View
* 如果控件的位置有变化,那要在变化之后再调用此方法
* @param view 需要扩大点击范围的View
* @param left 点击区域的left
* @param top 点击区域的top
* @param right 点击区域的right
* @param bottom 点击区域的bottom
*/
public static void expandViewTouchDelegate(final View view,
final int left, final int top,
final int right, final int bottom) {
((View) view.getParent()).post(new Runnable() {
@Override
public void run() {
Rect bounds = new Rect();
view.setEnabled(true);
view.getHitRect(bounds);
bounds.top -= top;
bounds.bottom += bottom;
bounds.left -= left;
bounds.right += right;
TouchDelegate touchDelegate = new TouchDelegate(bounds, view);
if (view.getParent() instanceof View) {
((View) view.getParent()).setTouchDelegate(touchDelegate);
}
}
});
}
如果想要取消:
/**
* 还原View的触摸和点击响应范围,最小不小于View自身范围
*
* @param view 需要扩大点击范围的View
*/
public static void restoreViewTouchDelegate(final View view) {
((View) view.getParent()).post(new Runnable() {
@Override
public void run() {
Rect bounds = new Rect();
bounds.setEmpty();
TouchDelegate touchDelegate = new TouchDelegate(bounds, view);
if (view.getParent() instanceof View) {
((View) view.getParent()).setTouchDelegate(touchDelegate);
}
}
});
}
采取此种方法的两点注意:
- 若View的自定义触摸范围超出Parent的大小,则超出的那部分无效。
- 一个Parent只能设置一个View的TouchDelegate,设置多个时只有最后设置的生效。
对于TouchDelegate的用法其实是非常简单的。由于一个父控件只能允许一个子View扩大触摸区域,设置多个时只有最后设置的生效。那么遇到多个子View的情况需要怎么解决呢?
通过查找资料,发现已经有大神解决了链接:浅谈TouchDelegate的坑与用法以及ListView Tips & Tricks #5: Enlarged Touchable Areas