5

ユーザーが画面をスワイプしたときに反転する ViewFlipper 内に ListView があります。ListView をクリックすると、ブラウザーが開きます。スワイプしていると、ListView へのタッチとして検出され、ブラウザが開くことがあります。これは煩わしい場合があります。どうすればこれを防ぐことができますか?

class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                    return false;
                // right to left swipe
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    viewFlipper.setInAnimation(slideLeftIn);
                    viewFlipper.setOutAnimation(slideLeftOut);
                    viewFlipper.showNext();
                } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    viewFlipper.setInAnimation(slideRightIn);
                    viewFlipper.setOutAnimation(slideRightOut);
                    viewFlipper.showPrevious();
                }

                if (viewFlipper.getDisplayedChild() == 0) {
                    // TODO: light up left
                    flipperPosition = 0;
                } else if (viewFlipper.getDisplayedChild() == 1) {
                    // TODO: light up middle
                    flipperPosition = 1;
                } else if (viewFlipper.getDisplayedChild() == 2) {
                    // TODO: light up right
                    flipperPosition = 2;
                }
            } catch (Exception e) {
                System.out.println(e);
            }
            return false;
        }
    }

protected MotionEvent downStart = null;  

        public boolean onInterceptTouchEvent(MotionEvent event) {  

            switch(event.getAction()) {  
            case MotionEvent.ACTION_DOWN:  
                // keep track of the starting down-event  
                downStart = MotionEvent.obtain(event);  
                break;  
            case MotionEvent.ACTION_MOVE:  
                // if moved horizontally more than slop*2, capture the event for ourselves  
                float deltaX = event.getX() - downStart.getX();  
                if(Math.abs(deltaX) > ViewConfiguration.getTouchSlop() * 2)  
                    return true;  
                break;  
            }  

            // otherwise let the event slip through to children  
            return false;  
        }  
4

2 に答える 2

14

これは通常、親ビューのonInterceptTouchEventメソッドを介して行われます。onInterceptTouchEventビューの子が行う前に、タッチ イベントを確認する機会があります。以前にタッチ イベントを処理していた子ビューがonInterceptTouchEvent返された場合、それ以降のイベントは、通常の処理のために親のメソッドに送信されます。また、イベントがビュー階層を下って通常のターゲットに移動するときに、イベントを返し、単純にスパイすることもできます。trueACTION_CANCELonTouchEventfalse

onInterceptTouchEvent基本的に、フリングを検出している親ビューでこれを行う必要があります。

  • で、タッチACTION_DOWNの位置を記録します。戻るfalse
  • ACTION_MOVEで、最初のタッチダウン位置と現在の位置の間のデルタを確認します。しきい値を超えている場合 (フレームワークはViewConfiguration#getScaledTouchSlop()、またはこのようなものからの他の適切な値を使用しますViewConfiguration) を返しtrueます。
  • に基づいて通常どおりフリングを検出して処理しonTouchEventます。

インターセプトすると、ListViewはそのタッチ処理をキャンセルし、リスト項目で不要なタップ イベントを取得しなくなります。ListViewまた、ユーザーがリストを縦方向にスクロールし始めたときに、その親がイベントをインターセプトすることを許可しないように設定されています。つまり、ユーザーがリストをずさんに縦方向にスクロールしても、横方向のフリングが誤って発生することはありません。

これは、標準の Android ランチャーやニュースや天気予報などで、スクロール/タップ可能なコンテンツを左右にページングする方法です。

于 2010-09-30T21:23:33.227 に答える
1

オンタッチイベント(「クリック」)にSimpleOnGestureListener.onSingleTapConfirmed(MotionEvent)を使用してみましたか?これは、検出器がユーザーの最初のタップが実際にはタップであり、ダブルタップ(またはできればフリング)ではないと確信した後にのみ呼び出されます。

class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        // Code...
    }
}
于 2010-09-30T19:51:11.580 に答える