【问题标题】:Detect scale and translate gestures without ScaleGestureDetector在没有 ScaleGestureDetector 的情况下检测比例和翻译手势
【发布时间】:2012-11-11 10:07:33
【问题描述】:

我尝试为 API 级别 7 实现多点触控手势检测。这意味着我没有 ScaleGestureDetector。目前我有这样的东西,但效果不好,我对它有更多的开放性问题,而不是完全理解:

public boolean onTouchEvent(MotionEvent ev) 
{
   final int action = ev.getAction();
   switch (action & MotionEvent.ACTION_MASK) // why mask it with ACTION_MASK?
   {
      case MotionEvent.ACTION_DOWN: 
      {
         mLastTouchX=ev.getX();
         mLastTouchY=ev.getY();
         mActivePointerId = ev.getPointerId(0);
         break;            
      }
     case MotionEvent.ACTION_POINTER_DOWN: 
     {
        mLastTouchX2=ev.getX();
        mLastTouchY2=ev.getY();
        if (ev.getPointerCount()>1)
         mActivePointerId2 = ev.getPointerId(1);
        break;
     }
     case MotionEvent.ACTION_MOVE: 
     {
        int   pointerIndex;
        float x=0.0f,y=0.0f;

        try
        {
           if ((mActivePointerId!=INVALID_POINTER_ID) || (mActivePointerId2!=INVALID_POINTER_ID))
           {
              // get one of the active pointers - unfortunately here I'm not sure which one is the active one so I only can guess
              pointerIndex= ev.findPointerIndex(mActivePointerId);
              x= ev.getX(pointerIndex);
              y= ev.getY(pointerIndex);
           }
           if ((mActivePointerId!=INVALID_POINTER_ID) && (mActivePointerId2!=INVALID_POINTER_ID))
           {
              float d1,d2;

              pointerIndex = ev.findPointerIndex(mActivePointerId2);
              if (pointerIndex<0) return false;
              float x2 = ev.getX(pointerIndex);
              float y2 = ev.getY(pointerIndex);

              d1=android.util.FloatMath.sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
              d2=android.util.FloatMath.sqrt((mLastTouchX-mLastTouchX2)*(mLastTouchX-mLastTouchX2)+
                                  (mLastTouchY-mLastTouchY2)*(mLastTouchY-mLastTouchY2));                  

              if ((d1>0) && (d2>0)) // seems to be a scale gesture with two pointers
              {
                 float w,h,s;

                 transOffsetX=0.0f;
                 transOffsetY=0.0f;
                 s=d1/d2;
                 mScaleFactor*=s;
                 matrix.postScale(s,s);
                 w=(scrWidth-(scrWidth*s))/2.0f;
                 h=(scrHeight-(scrHeight*s))/2.0f;

                 matrix.postTranslate(w,h);
                 imgOffsetX+=w;
                 imgOffsetY+=h;                                    
              }

              mLastTouchX2 = x2;
              mLastTouchY2 = y2;
           }
           else if (mScaleFactor==1.0) // seems to be a translate gesture with only one pointer
           {
              mScaleFactor=1.0f;
              transOffsetX+=(x-mLastTouchX);
              transOffsetY+=(y-mLastTouchY);
              matrix.setTranslate(transOffsetX,transOffsetY);
           }

           if ((mActivePointerId!=INVALID_POINTER_ID) || (mActivePointerId2!=INVALID_POINTER_ID))
           {             
              mLastTouchX = x;
              mLastTouchY = y;
           }
        }
        catch (ArrayIndexOutOfBoundsException aioobe)
        {
           // this is really strange, this exception can be caused by
           // pointerIndex= ev.findPointerIndex(mActivePointerId);
           // x= ev.getX(pointerIndex);
           // above which seems to be a Android bug?
        }
        break;
     }
     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_POINTER_UP: 
     {
        breakMapThread=true;
        mActivePointerId = INVALID_POINTER_ID;
        mActivePointerId2 = INVALID_POINTER_ID;

        // gestrue seems to be finished so trigger update of the view here
        ...

        break;
     }
  }      
  return true;

}

整个事情真的很糟糕。缩放手势会导致较高的额外翻译,单击视图也会导致翻译,并且翻译不是很准确。除此之外,我还发现了一些似乎从未使用过的运动事件常量 ACTION_POINTER_1/2/3_DOWN/UP。所以我绝对不确定我的整个赋值形式 _DOWN/_UP 到指针一和二是否正确。

有什么想法、提示和技巧可以让这件事发挥作用吗?

【问题讨论】:

    标签: android scale multi-touch gesture translate


    【解决方案1】:

    一个想法是找到 ScaleGestureDetector 的来源并将其包含到您的项目中。 但是存在问题:有时系统会检测到单击和长按(尤其是当手指超出窗口边界时)。

    【讨论】:

      猜你喜欢
      • 2011-12-12
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 2020-10-15
      • 2015-02-23
      • 1970-01-01
      • 2022-11-05
      • 1970-01-01
      相关资源
      最近更新 更多