2015-10-22 34 views
1

我們有一個Android應用程序,旨在安裝在崎嶇地形中運行的車輛的短跑線上,因此一切都非常不穩固。我們已經發現,在這種情況下在屏幕上單擊一下是很困難的,因爲點擊通常被解釋爲小拖動。在Android按鈕中增加觸控坡度

我需要的是觸摸事件,在手指出現之前有一點擺動,被解釋爲點擊而不是拖動。我一直在閱讀Android的「觸控技術」,我可以看到他們已經對此進行了說明。我真正需要了解的是如何增加Android button小部件的子類的「觸摸斜率」。

這可能只是幾行代碼?或者我需要自己執行onInterceptTouchEvent和'onTouchEvent`?如果是後者,任何人都可以給我一些關於這將如何工作的方向?

回答

1

這是我做的,希望能幫助你們。

private Rect mBtnRect; 
yourView.setOnTouchListener(new OnTouchListener() { 
    private boolean isCancelled = false; 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      isCancelled = false; 
      parent.requestDisallowInterceptTouchEvent(true); // prevent parent and its ancestors to intercept touch events 
      createClickArea(v); 
      // your logic touch down 
      return true; 
     case MotionEvent.ACTION_UP: 
      if(!isCancelled) { 
       // Click logic 
      } 
      // release mBtnRect when cancel or up event 
      mBtnRect = null; 
      return true; 
     case MotionEvent.ACTION_CANCEL: 
      isCancelled = true; 
      releaseTouch(parent, v); 
      return true; 
     case MotionEvent.ACTION_MOVE: 
      if(!isBelongTouchArea(event.getRawX(), event.getRawY())) { 
        isCancelled = true; 
        releaseTouch(parent, v); 
      } 
      return true; 
     default: 
      break; 
    } 
} 
// Create the area from the view that user is touching 
private final void createClickArea(View v) { 
    // for increase rect area of button, pixel in used. 
    final int delta = (int) mContext.getResources().getDimension(R.dimen.extension_area); 
    final int[] location = new int[2]; 
    // Get the location of button call on screen 
    v.getLocationOnScreen(location); 
    // Create the rect area with an extension defined distance. 
    mBtnRect = new Rect(v.getLeft() - delta, location[1] + v.getTop() - delta, v.getRight(), location[1] + v.getBottom() + delta); 
} 
//Check the area that contains the moved position or not. 
private final boolean isBelongTouchArea(float rawX, float rawY) { 
    if(mBtnRect != null && mBtnRect.contains((int)rawX, (int)rawY)) { 
     return true; 
    } 
    return false; 
} 
private void releaseTouch(final ListView parent, View v) { 
    parent.requestDisallowInterceptTouchEvent(false); 
    mBtnRect = null; 
    // your logic 
} 
1

對於我們簡單的用例與android.opengl.GLSurfaceView,我們解決了你說了同樣的問題,「如果手勢移動的距離小於some_threshold,其解釋爲點擊」 。我們使用兩個2D點之間的標準歐幾里德距離= sqrt((deltaX)^2 + (deltaY)^2)),其中deltaXdeltaY是在用戶的運動手勢中移動的距離的分量。

更準確地說,讓(x1,y1)是其中用戶的手指手勢「開始」座標,讓(x2,y2)是所述手勢「結束」座標。

然後,deltaX = x2 - x1(或者也可以x1 - x2但跡象不要緊,距離「我們CZ平方值),同樣爲deltaY

從這些增量,我們計算的歐氏距離,如果它小於閾值時,用戶可能想要它成爲一個點擊但由於設備的觸摸污的,它得到了歸類爲舉動手勢代替的點擊。

實現明智的,是的,我們推翻了android.view.View#onTouchEvent(MotionEvent)

  • 記錄(x1,y1)當蒙面行動是android.view.MotionEvent#ACTION_POINTER_DOWNandroid.view.MotionEvent#ACTION_DOWN
  • 當蒙面行動是android.view.MotionEvent#ACTION_MOVE(x2,y2)很容易從事件的getXgetY方法(見corresponding documentation