web-dev-qa-db-ja.com

Androidのビューにジェスチャー検出器を追加する方法

私は、プロジェクトのサブビューにジェスチャー検出器を追加するのに苦労していました。親のonTouchEventまたは子のonTouchEventをオーバーライドしますか? OnTouchListenerを作成し、そこにジェスチャー検出器を追加しますか? documentation は、アクティビティ自体にジェスチャ検出器を追加する方法の例を示していますが、ビューに追加する方法は明確ではありません。ビューをサブクラス化する場合も同じプロセスを使用できます(例 here )が、サブクラス化せずにジェスチャを追加したい。

これ は、私が見つけることができる最も近い他の質問ですが、ImageViewの一般的なケースではなく、Viewでの投げるジェスチャーに固有です。また、trueまたはfalseを返すタイミングについて、これらの回答には不一致があります。

それがどのように機能するかを理解するために、私はスタンドアロンのプロジェクトを作成しました。私の答えは以下です。

17
Suragch

この例では、ビューにジェスチャー検出器を追加する方法を示します。レイアウトは、アクティビティ内の単一のViewです。同じ方法を使用して、ジェスチャ検出器を任意のタイプのビューに追加できます。

enter image description here

緑のViewにジェスチャー検出器を追加します。

MainActivity.Java

基本的な考え方は、ビューに OnTouchListener を追加することです。通常、ここではすべての生のタッチデータ(_ACTION_DOWN_、_ACTION_MOVE_、_ACTION_UP_など)を取得しますが、それを自分で処理する代わりに、ジェスチャ検出器に転送しますタッチデータの解釈を行います。

SimpleOnGestureListener を使用しています。このジェスチャ検出器の良いところは、必要なジェスチャをオーバーライドするだけで済むことです。ここの例では、それらの多くを含めました。不要なものは削除できます。 (ただし、常にtrueonDown()に返す必要があります。trueを返すことは、イベントを処理していることを意味します。falseを返すと、システムはそれ以上タッチイベントを提供しなくなります。)

_public class MainActivity extends AppCompatActivity {

    private GestureDetector mDetector;

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

        // this is the view we will add the gesture detector to
        View myView = findViewById(R.id.my_view);

        // get the gesture detector
        mDetector = new GestureDetector(this, new MyGestureListener());

        // Add a touch listener to the view
        // The touch listener passes all its events on to the gesture detector
        myView.setOnTouchListener(touchListener);
    }

    // This touch listener passes everything on to the gesture detector.
    // That saves us the trouble of interpreting the raw touch events 
    // ourselves.
    View.OnTouchListener touchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // pass the events to the gesture detector
            // a return value of true means the detector is handling it
            // a return value of false means the detector didn't 
            // recognize the event
            return mDetector.onTouchEvent(event);

        }
    };

    // In the SimpleOnGestureListener subclass you should override 
    // onDown and any other gesture that you want to detect.
    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onDown(MotionEvent event) {
            Log.d("TAG","onDown: ");

            // don't return false here or else none of the other 
            // gestures will work
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.i("TAG", "onSingleTapConfirmed: ");
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            Log.i("TAG", "onLongPress: ");
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            Log.i("TAG", "onDoubleTap: ");
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, 
                                float distanceX, float distanceY) {
            Log.i("TAG", "onScroll: ");
            return true;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                               float velocityX, float velocityY) {
            Log.d("TAG", "onFling: ");
            return true;
        }
    }
}
_

このプロジェクトを実行するには簡単なセットアップなので、試してみることをお勧めします。ログイベントが発生する方法とタイミングに注意してください。

38
Suragch

ビューに対してのみダブルタップを検出するkotlinのショートバージョン:

val gestureDetector = GestureDetector(activity, object : GestureDetector.SimpleOnGestureListener() {
    override fun onDoubleTap(e: MotionEvent?): Boolean {
        Log.d("myApp", "double tap")
        return true
    }
})
myView.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event) }

myViewをクリック可能にすることを忘れないでください

5
Palejandro