我正在使用SimpleOnGestureListener来检测onSingleTapUp事件和视图。
该视图的比例因子为5,因此1个屏幕像素对应于我视图中的5个像素:
view.setScaleX(5);
view.setScaleY(5);
我面临的问题是没有正确检测到Tap事件。我查看了
SimpleOnGestureListener
的源代码,相关部分是:SingleTapUp()
侦听器触摸点的行进距离计算为
我认为未可靠检测到Tap的原因是,触摸点的距离计算依赖于视图的缩放局部坐标(
e.getX()
和e.getY()
),而不是原始坐标(e.getRawX()
和e.getRawY()
)。由于比例因子,手指在屏幕上的微小移动会导致
e.getX()
和e.getY()
发生较大变化。我对代码的解释正确吗?如果是这样,我该如何解决此问题?
现在,我的解决方法是拦截没有比例因子的
View
上的所有事件,然后自己将MotionEvents
调度到具有比例因子的视图中。它运作良好,但我仍然对我对android代码的分析是否正确感兴趣。
我正在使用android 4.4
最佳答案
恕我直言,您对代码的分析是正确的!
在探索源代码时发现了一些附加信息:
mTouchSlopSquare
中定义的距离和已初始化的here(存储为原始值的平方,仅用于优化)GestureDetector
的构造函数(应该是,因为第二个已经过时了),则此值将根据this line com.android.internal.R.dimen.config_viewConfigurationTouchSlop
解决方法
作为解决方法,我建议您访问
mTouchSlopSquare
的私有成员GestureDetector
并在此距离计算中添加比例因子。请参阅下面的代码:
// Utility method
public static boolean fixGestureDetectorScale(GestureDetector detector, float scale) {
try {
Field f = GestureDetector.class.getDeclaredField("mTouchSlopSquare");
f.setAccessible(true);
int touchSlopSquare = (int) f.get(detector);
float touchSlop = (float) Math.sqrt(touchSlopSquare);
//normalize touchSlop
touchSlop /= scale;
touchSlopSquare = Math.round(touchSlop * touchSlop);
f.set(detector, touchSlopSquare);
} catch (NoSuchFieldException e) {
e.printStackTrace();
return false;
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
}
return true;
}
// usage
fixGestureDetectorScale(mGestureDetector, scale);
view.setScaleX(scale);
view.setScaleY(scale);
我检查了一下,它对我有用。