2017-01-20 2 views
1

OnSwipeTouchListenerを作成するために、インターネットにリスナークラスがあります。ユーザーがダウンスワイプをするときに、このリスナーが確定することができ、アップ、左または右:私は(機能onSwipeLを追加したいと思い、今文字をOnSwipeTouchListenerでLにする

findViewById(R.id.framelayout).setOnTouchListener(new OnSwipeTouchListener(this) { 
      @Override 
      public void onSwipeDown() { 
       Toast.makeText(MainActivity.this, "Down", Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void onSwipeLeft() { 
       Toast.makeText(MainActivity.this, "Left", Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void onSwipeUp() { 
       Toast.makeText(MainActivity.this, "Up", Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void onSwipeRight() { 
       Toast.makeText(MainActivity.this, "Right", Toast.LENGTH_SHORT).show(); 
      } 
     }); 

public class OnSwipeTouchListener implements View.OnTouchListener { 

    private GestureDetector gestureDetector; 

    protected OnSwipeTouchListener(Context c) { 
     gestureDetector = new GestureDetector(c, new GestureListener()); 
    } 

    public boolean onTouch(final View view, final MotionEvent motionEvent) { 
     return gestureDetector.onTouchEvent(motionEvent); 
    } 

    private final class GestureListener extends GestureDetector.SimpleOnGestureListener { 

     private static final int SWIPE_THRESHOLD = 100; 
     private static final int SWIPE_VELOCITY_THRESHOLD = 100; 

     @Override 
     public boolean onDown(MotionEvent e) { 
      return true; 
     } 

     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      try { 
       float diffY = e2.getY() - e1.getY(); 
       float diffX = e2.getX() - e1.getX(); 
       if (Math.abs(diffX) > Math.abs(diffY)) { 
        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffX > 0) { 
          onSwipeRight(); 
         } else { 
          onSwipeLeft(); 
         } 
        } 
       } else { 
        if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffY > 0) { 
          onSwipeDown(); 
         } else { 
          onSwipeUp(); 
         } 
        } 
       } 
      } catch (Exception exception) { 
       exception.printStackTrace(); 
      } 
      return false; 
     } 
    } 

    public void onSwipeRight() { 
    } 

    public void onSwipeLeft() { 
    } 

    public void onSwipeUp() { 
    } 

    public void onSwipeDown() { 
    } 
} 

これは私がそれを使用する方法です)。この機能は、ユーザーが指で文字Lを作ったときです。これはonSwipeDown()+ onSwipeRight()のようなものです。

最高は)(onSwipeDoubleL機能させることになります。これは、ユーザが指で反転した2重のLを作るときです。

  • onSwipeDown()+ onSwipeRight()
  • onSwipeDown()+ onSwipeLeft()

が可能ということです:それは作ると同時に、のようなものですか?

答えて

0

あなたはこのジェスチャーを必要とする理由私は本当に理解することはできません。しかしここに私の解決策があります。タッチイベントを捕捉する必要があるので、onTouchEventメソッドをオーバーライドしてください。ここで、画面上の指の指数を読む必要があります。

我々は、複数のタッチが「左指」よりも多くのX座標の指のための右の指標を適用しました場合。正しいインデックスが見つかったとは言えません。だから私はインデックス座標をチェックします。

次のステップでは、開始点を保存して下に移動します。画面上に2本の指がある場合は、左右の指を左(または望むように)だけ点検してください。

我々はより多くの最小THENとき「ダウン」距離イベントをキャッチし、我々は右/左に移動を開始した場合、我々はそれから今までの距離を計算し、新たなスタートポイントを保存する必要があります。

ユーザーが左/右に移動してからmin以上の距離を移動するのを待ちます。結局のところ、「左」と「右」の指で、またはちょうど左(ワンタッチ)で成功を確認します。

我々はまた、移動時(ミス、エラー)不正確考える必要があります。ユーザーは下に移動することも完全に正しいままにすることもできないため、ソリューションはこのパラメータに大きく依存します。範囲と精度のパラメータのバランスをとってジェスチャーを快適にコントロールする必要があります。

コードは最適化されておらず、基本的な考え方のみを示しています。たぶんあなたはもっと小さなソリューションを見つけるでしょう。私の英語レベルには申し訳ありません

public class MainMenuActivity extends AppCompatActivity { 

    boolean movingDownL = false; 
    boolean movingDownR = false; 
    boolean movingLeft = false; 
    boolean movingRight = false; 

    boolean movingSuccessL = false; 
    boolean movingSuccessR = false; 

    // Deviation in pixels from the route (error value) 
    int downInaccuracy = 30; // Down 
    int lnrInaccuracy = 10; // Left and Right 

    // Minimum distance to apply move (300 px in down and 100 to the left/right) 
    int downMinDistance = 300; 
    int lnrMinDistance = 50; 

    Point oldCoordsL = new Point(0, 0); // Old coordinates left 
    Point oldCoordsR = new Point(0, 0); // Old coordinates right 
    Point startPointL = new Point(0, 0); 
    Point startPointR = new Point(0, 0); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main_menu); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     int pIndexL = event.findPointerIndex(event.getPointerId(0)); 
     int pIndexR = 0; 

     // If we have more than 1 touch read second finger index 
     if(event.getPointerCount() > 1) pIndexR = event.findPointerIndex(event.getPointerId(1)); 

     // Check if we do not mistake when read fingers id 
     if(event.getPointerCount() > 1 && event.getX(pIndexL) > event.getX(pIndexR)) { 
      int tmp = pIndexR; 
      pIndexR = pIndexL; 
      pIndexL = tmp; 
     } 

     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       movingDownL = true; // Start moving fingers 
       movingDownR = true; 
       movingSuccessL = false; 
       movingSuccessR = false; 

       // Get start point left and right if we need 
       if(event.getPointerCount() > 1) { 
        startPointR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR)); 
        oldCoordsR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR)); 
       } 

       startPointL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL)); 
       oldCoordsL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL)); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       // Add right finger handler 
       if(event.getPointerCount() > 1) { 
        if(!movingDownR) { 
         // Check if we still moving to down 
         if(Math.abs(oldCoordsR.x - event.getX(pIndexR)) < downInaccuracy && 
           oldCoordsR.y < event.getY(pIndexR)) break; 
         // Start moving to the right 
         if(Math.abs(oldCoordsR.y - event.getY(pIndexR)) < lnrInaccuracy && 
           oldCoordsR.x > event.getX(pIndexR) && !movingRight) { 
          movingRight = true; 
          startPointR = new Point(new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))); 
         } 
        }else { 
         if (Math.abs(oldCoordsR.x - event.getX(pIndexR)) > downInaccuracy || 
           oldCoordsR.y < event.getY(pIndexR)) { 
          movingDownR = false; 
          break; 
         } else if(findDistance(startPointR, 
           new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= downMinDistance){ 
          // Start moving to the left/right 
          movingDownR = false; 
         } 
        } 
       } 

       // Left finger handler by default even if we got only one touch 
       // Check if we need move to any side 
       if(!movingDownL) { 
        // Check if we still moving to down 
        if(Math.abs(oldCoordsL.x - event.getX(pIndexL)) < downInaccuracy && 
          oldCoordsL.y < event.getY(pIndexL)) break; 
        // Start moving to the left 
        if(Math.abs(oldCoordsL.y - event.getY(pIndexL)) < lnrInaccuracy && 
          oldCoordsL.x < event.getX(pIndexL) && !movingLeft) { 
         movingLeft = true; 
         startPointL = new Point(new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))); 
        } 
       }else { 
        if (Math.abs(oldCoordsL.x - event.getX(pIndexL)) > downInaccuracy || 
          oldCoordsL.y > event.getY(pIndexL)) { 
         movingDownL = false; 
         break; 
        } else if(findDistance(startPointL, 
          new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= downMinDistance){ 
         // Start moving to the left/right 
         movingDownL = false; 
        } 
       } 

       // Left move handler 
       if(movingLeft) { 
        if (Math.abs(oldCoordsL.y - event.getY(pIndexL)) > lnrInaccuracy || 
          oldCoordsL.x > event.getX(pIndexL)) { 
         movingLeft = false; 
         break; 
        } else if(findDistance(startPointL, 
          new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= lnrMinDistance) { 
         movingLeft = false; 
         movingSuccessL = true; // L from left finger is OK 
        } 
       } 

       // Right move handler 
       if(movingRight) { 
        if (Math.abs(oldCoordsR.y - event.getY(pIndexR)) > lnrInaccuracy || 
          oldCoordsR.x < event.getX(pIndexR)) { 
         movingRight = false; 
         break; 
        } else if(findDistance(startPointR, 
          new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= lnrMinDistance) { 
         movingRight = false; 
         movingSuccessR = true; // L from right finger is OK 
        } 
       } 

       if(movingSuccessL && movingSuccessR) { 
        Toast.makeText(this, "Yeah, it's look like double L", Toast.LENGTH_SHORT).show(); 
       } else if(movingSuccessL) Toast.makeText(this, "Yeah, it's look like L", Toast.LENGTH_SHORT).show(); 

       oldCoordsL = new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL)); 
       oldCoordsR = new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR)); 

       break; 
      case MotionEvent.ACTION_UP: 
       movingDownL = false; 
       movingDownR = false; 
       movingLeft = false; 
       movingRight = false; 
       break; 
      default: 
       return false; 
     } 

     return true; 
    } 

    private double findDistance(Point p1, Point p2) { 
     return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); 
    } 
} 
+0

私は画面に触れると、「ええと、ダブルLのようです」というメッセージが表示されます。 –

+0

それは変です。 2つのデバイスでアプリをテストしましたが、すべて正常に動作します。私のコードを正しくコピーしましたか?または何かを変える?movingSuccessLとmovingSuccessRは常に偽であるため、タッチでメッセージを作成することはできません –

+0

これは残念です。問題は、私が二重Lを実行するときに私はデバッグをさまざまな時間に表示します。これは大きな問題です。その後にフラグメントを呼び出さなければならず、アプリケーションはこのフラグメントをさまざまな時間呼び出す必要があります。 1回だけ電話をかけるにはどうすればいいですか? –

0

2つのオプションがあります。

  • まず - いくつかのブール値を使用します。 isSwipedRight(例として)。 onSwipeRight()をチェックしてください。isSwipedDownの場合はtrue、そうであれば処理してください。 onSwipeDown()では、booleanをtrueに設定し、それ以外の場合はfalseをfalseに設定します。
  • 独自のonTouchListenerを作成し、自分で距離を測定します。
関連する問題