4

画面全体をカバーするビュー (としましょう) と、その一部のみをカバーParentViewする子内部ビューがあります。に反応させながら、に反応さChildViewせたい。1つと1つを付けてそうしようとしています。ChildViewonSingleTapUp()ParentViewonFling()SimpleOnGestureListenerChildViewSimpleOnGestureListenerParentView

onSingleTapUp()fromを受け入れるにはChildView、そのリスナーonDown()が true を返す必要があります。しかし、これを行うと、 に関連付けられているリスナーは、 のリスナーParentViewによって取得されるため、モーション イベントを聞くことができなくなりますChildView。は false を返しますが、イベントはChildViewのリスナーonFling()に流れません。ParentView

親ビューのリスナーがフリング ジェスチャをキャッチし、子ビューのリスナーがタップ ジェスチャをキャッチするにはどうすればよいですか?

状況を説明するのにソース コードは必要ないと思いますが、ChildViewリスナーをセットアップするためのスニペットを次に示します。

ChildView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return singleTapGestureDetector.onTouchEvent(motionEvent);
    }
});

ParentView1 つの回避策として、との両方ChildViewのリスナーを処理し、のリスナーonFling()のみを処理することもできますが、その場合、 を越えてフリングが発生することはありません(子の外側で開始してから、子の中で終了するなど)。信じる。ChildViewonSingleTapUp()ChildView

4

1 に答える 1

2

私は自分の解決策が好きではありませんが、これを行う方法を見つけました。うまくいけば、他の誰かが将来より良い答えを投稿するか、少なくとも私の回避策が他の誰かにとって役に立ちます。

質問で説明したように、問題はジェスチャ リスナーがどのように機能するかにあります。onSingleTapUp()子ビューがイベントをキャッチするには、 true on を返しますonDown()onTouch()ただし、これを行うと、子ビューがイベントに関心がなくなったと宣言した後でも、後続の一連のイベントは親ビューに移動しません。onTouch()ジェスチャ検出器が false を返したときに子内で親を強制的に呼び出すと、onTouch()親の onFling() が呼び出されますが、最初のMouseEvent引数は子ビューの によって消費されるため、NULL になりますonTouch()

これは非常に基本的なジェスチャ検出シナリオのように見えるため、何かが欠けているに違いありません。とにかく、合理的な方法でこれを行う方法を見つけることができませんでした。

したがって、私の回避策は TouchListenerService をシングルトンにすることです。

子ビューと親ビューの両方に次の行があります

view.setOnTouchListener(TouchListenerService.Instance());

TouchListenerService は次のように開始します。

public class TouchListenerService
    extends GestureDetector.SimpleOnGestureListener
    implements View.OnTouchListener {

    // some code to implement singleton

    public SingleTapUpHandler SingleTapUpHandler;
    public FlingHandler FlingHandler;

    private View _touchingView;

    GestureDetector gestureDetector;

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (gestureDetector == null)
            gestureDetector =  new GestureDetector(_touchListenerService);

        _touchingView = view;
        boolean result = gestureDetector.onTouchEvent(motionEvent);
        _touchingView = null;
        return result;
    }
    // and some more code

同じイベントハンドラーであるため、親ビューはonFling()イベントを正常にキャッチし、子ビューはSingleTapUpHandlerクリックイベントを処理するように設定できます。

于 2012-09-30T06:15:23.183 に答える