????????之前在重新翻看view触摸事件传递的源码时,意外在View源码中发现了一个之前不曾注意到的api:TouchDelegate,定义非常简单,但是面对一些特殊的view操作需求却有奇效。
定义是:
/**
* The delegate to handle touch events that are physically in this view
* but should be handled by another view.
*/
private TouchDelegate mTouchDelegate = null;
使用位置在:
public boolean onTouchEvent(MotionEvent event) {
。。。。
if (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}
。。。。
}
设置方法:
setTouchDelegate(TouchDelegate delegate) {}
就可以使用了。
源代码在:
android.view.TouchDelegate
唯一的构造函数:
public TouchDelegate(Rect bounds, View delegateView)
bounds:
Bounds in local coordinates of the containing view that should be mapped to the delegate view。
大意是:应映射到代理视图的包含视图的局部坐标中的边界。
delegateView:
The view that should receive motion events。
应该接收运动事件的视图。
实现分发事件判断是:
boolean onTouchEvent(MotionEvent event){
......
if (sendToDelegate) {
final View delegateView = mDelegateView;
if (hit) {
// Offset event coordinates to be inside the target view
event.setLocation(delegateView.getWidth() / 2, delegateView.getHeight() / 2);
} else {
// Offset event coordinates to be outside the target view (in case it does
// something like tracking pressed state)
int slop = mSlop;
event.setLocation(-(slop * 2), -(slop * 2));
}
//进入到代理view的事件分发流程。
handled = delegateView.dispatchTouchEvent(event);
}
.......
}
使用场景:
- ????????可以增加TargetView的触摸范围,实现扩大点击区域优化用户体验,将周围的view的代理view设置为此TargetView,那么此时周围view的触摸事件都会分发到TargetView上。
- ? ? ? ? 源码中可以发现对于代理分发事件的处理是很直接的, 代理view不为null就直接将事件全部分发给代理view,同时代理view的引用可以随时设置,即setTouchDelegate(),那么可以在触摸事件持续过程中更换代理view,以达到单次事件过程中传递给多个view的目的。
|