【问题标题】:Use ScaleGestureDetector with GestureDetector?将 ScaleGestureDetector 与 GestureDetector 一起使用?
【发布时间】:2017-11-08 06:28:10
【问题描述】:

在我的 Android 应用程序中,我有一个 ImageView,我希望用户能够向左/向右/向上/向下移动它以将图像(静态地图)更改为相邻的图像。但除此之外,我还想要捏缩放功能和地图本身。

我可以让投掷或捏缩放工作,但不能一起工作。我正在使用GestureDetector(带有SimpleOnGestureListener)进行投掷。我正在使用ScaleGestureDetector(来自Making Sense of Multitouch)进行缩放。

困难在于确定在触摸动作时调用哪个手势侦听器。这不是编码问题,而是逻辑问题。单指触摸动作,是弹跳还是缩放?即使使用捏合缩放,初始 MotionEvent 也是 ACTION_DOWN。我一直在尝试使用图像大小(固有的还是缩放的?)作为决策点。但是使用 ACTION_DOWN 的初始缩放操作(当图像大小是固有的并且我想放大它时)似乎让我无法理解。

以前有没有人成功解决过这个问题?

【问题讨论】:

    标签: android-imageview multi-touch pinchzoom onfling


    【解决方案1】:

    您可以将事件传递给两个手势检测器。

    在“更复杂的缩放示例”下查看http://developer.android.com/training/gestures/scale.html

    public boolean onTouchEvent(MotionEvent event) {
        boolean retVal = mScaleGestureDetector.onTouchEvent(event);
        retVal = mGestureDetector.onTouchEvent(event) || retVal;
        return retVal || super.onTouchEvent(event);
    }
    

    当然,鉴于 Ratatat 引用的错误,在上面的示例中永远不会调用 super.onTouchEvent,这可能会也可能不会,这取决于您的用例。

    【讨论】:

    • 我试过这个和 Ratatat 的回答,这个给了我更好的结果。在处理同时平移和缩放时,如果您使用此答案,则可以只处理 onScroll 回调中的任何平移和 onScale 中的任何缩放,而不是尝试根据缩放动作的 focusX/focusY 中的移动进行平移。
    • 如果希望 OR 运算符的两边都被调用,可以使用| 代替||。喜欢:return mScaleGestureDetector.onTouchEvent(event) | mGestureDetector.onTouchEvent(event) | super.onTouchEvent(event);
    【解决方案2】:

    Ratatat's answer 的想法是可以的,但是即使我们不想滚动,我们仍然应该将事件传递给gestureDetector,否则它会被搞砸。

    我最终得到了这样的结果:

    scaleDetector = new ScaleGestureDetector( ... );
    
    gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            if (scaleDetector.isInProgress()) {
                // don't allow scrolling while scaling
                return false;
            }
    
            // handle scrolling
    
            return true;
        }
    }
    

    然后onTouchEvent的实现应该像aij's answer中的那样:

    boolean result = scaleDetector.onTouchEvent(event);
    result = gestureDetector.onTouchEvent(event) || result;
    return result || super.onTouchEvent(event);
    

    【讨论】:

      【解决方案3】:

      终于在一个链接上找到了答案: http://code.google.com/p/android/issues/detail?id=42591

      @Override
      public boolean onTouchEvent(MotionEvent event) {
          boolean result = mScaleGestureDetector.onTouchEvent(event);
      
          // result is always true here, so I need another way to check for a detected scaling gesture
          boolean isScaling = result = mScaleGestureDetector.isInProgress();
          if (!isScaling) {
              // if no scaling is performed check for other gestures (fling, long tab, etc.)
              result = mCommonGestureDetector.onTouchEvent(event);
          }
      
          // some irrelevant checks...
      
          return result ? result : super.onTouchEvent(event);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-11
        • 2020-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多