Java GestureDetector.SimpleOnGestureListener不考虑视图比例因子?

Java GestureDetector.SimpleOnGestureListener不考虑视图比例因子?,java,android,touch,Java,Android,Touch,我正在使用一个视图来检测事件 视图的比例因子为5,因此1个屏幕像素对应于我的视图上的5个像素: view.setScaleX(5); view.setScaleY(5); 我面临的问题是没有准确检测到Tap事件。我查看了SimpleOnGestureListener的源代码,相关部分如下: 如果触摸点未移动超过某个阈值,则调用singletaup()侦听器 计算接触点的移动距离 我认为没有可靠地检测到抽头的原因是接触点的距离计算依赖于视图的缩放局部坐标(e.getX()和e.ge

我正在使用一个视图来检测事件

视图的比例因子为5,因此1个屏幕像素对应于我的视图上的5个像素:

  view.setScaleX(5);
  view.setScaleY(5);
我面临的问题是没有准确检测到Tap事件。我查看了
SimpleOnGestureListener
的源代码,相关部分如下:

  • 如果触摸点未移动超过某个阈值,则调用
    singletaup()
    侦听器
  • 计算接触点的移动距离
我认为没有可靠地检测到抽头的原因是接触点的距离计算依赖于视图的缩放局部坐标(
e.getX()
e.getY()
),而不是原始坐标(
e.getRawX()
e.getRawY()

由于比例因子,手指在屏幕上的微小移动将导致
e.getX()
e.getY()
中的较大变化

我对代码的解释正确吗?如果是,我如何解决这个问题

现在,我的解决方法是截取没有比例因子的
视图
上的所有事件,然后将
MotionEvents
自己分派到具有比例因子的视图

它工作得很好,但我仍然对我对android代码的分析是否正确感兴趣


我使用的是安卓4.4,你对代码的分析是正确的

只是在探索源代码时发现的一些附加信息:

  • 在变量中定义并初始化的距离(存储为原始值的平方,仅用于优化)
  • 如果您将上下文传递给
    GestureDetector
    的构造函数(应该是,因为第二个构造函数已过时),则此值等于
    com.android.internal.R.dimen.config\u viewConfigurationTouchSlop
    ,根据
  • 比较是在同一区域内进行的
变通办法 作为解决方法,我建议您访问
GestureDetector
的私有成员
mTouchSlopSquare
,并在距离计算中添加比例因子

请参见下面的我的代码:

// 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;
}


我已经检查过了,它对我有效。

@thumbmunkeys谢谢)
    // usage
    fixGestureDetectorScale(mGestureDetector, scale);
    view.setScaleX(scale);
    view.setScaleY(scale);