23

ユーザーがビューAをタッチし、ビューBの上を下にドラッグした場合、タッチイベントを検出するにはどうすればよいですか。ビューBでタッチイベントを検出したいのですが。

ビューBにタッチリスナーを追加しましたが、ユーザーが最初にAにタッチしてBをドラッグした場合、イベントを受信しません。

ここに画像の説明を入力してください

4

7 に答える 7

66

次のコードを使用して、リクエストを達成できます。

ビューの境界をテストするメソッド(以下のコードで使用)

    Rect outRect = new Rect();
    int[] location = new int[2];

    private boolean isViewInBounds(View view, int x, int y){
        view.getDrawingRect(outRect);
        view.getLocationOnScreen(location);
        outRect.offset(location[0], location[1]);
        return outRect.contains(x, y);
    }

2人でテストTextView

    final TextView viewA = (TextView)  findViewById(R.id.textView);
    final TextView viewB = (TextView)  findViewById(R.id.textView2);

セットアップビューA

までアクティブな状態を維持するには、空OnClickListenerが必要ですOnTouchListenerACTION_UP

    viewA.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {}
    });

    viewA.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int x = (int)event.getRawX();
            int y = (int)event.getRawY();
            if(event.getAction() == MotionEvent.ACTION_UP){
                if(isViewInBounds(viewB, x, y))
                    viewB.dispatchTouchEvent(event);
                else if(isViewInBounds(viewA, x, y)){
                    Log.d(TAG, "onTouch ViewA");
                    //Here goes code to execute on onTouch ViewA
                }
            }
            // Further touch is not handled
            return false;
        }
    });

セットアップビューB

これは、viewB を押して viewA にドラッグする場合にのみ必要です。

    viewB.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {}
    });

    viewB.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int x = (int)event.getRawX();
            int y = (int)event.getRawY();
            if(event.getAction() == MotionEvent.ACTION_UP){
                if(isViewInBounds(viewA, x, y))
                    viewA.dispatchTouchEvent(event);
                else if(isViewInBounds(viewB, x, y)){
                    Log.d(TAG, "onTouch ViewB");
                    //Here goes code to execute on onTouch ViewB
                }
            }
            // Further touch is not handled
            return false;
        }
    });

よろしく。

于 2012-11-22T02:42:08.810 に答える
1

ViewGroup.dispatchTouchEvent(MotionEvent ev)ビューAとビューBを含むViewGroupのオーバーライドメソッドが必要だと確信しています。元の実装では、コンテナが受信したときにターゲットビューを定義し、次のすべてのタッチイベントを受信またはMotionEvent.getAction() == MotionEvent.ACTION_DOWNまでターゲットビューにディスパッチします。MotionEvent.getAction() == MotionEvent.ACTION_UPMotionEvent.ACTION_CANCEL

あなたの場合、ターゲットビューはAまたはコンテナ自体です(コンテナonInterceptTouchEvent(MotionEvent ev)メソッドの実装に依存します)。したがって、このような動作をオーバーライドして、タッチイベントをターゲットビューだけでなく、タッチされた領域の下にあるすべてのビュー(たとえば、ビューB)にもディスパッチする必要があります。

興味のある方は、コードサンプルを共有していただければ、さらにサポートさせていただきます。

于 2012-10-19T18:34:06.557 に答える
1

View Aで、次のようにオーバーライドonTouchEventします。

@Override
public boolean onTouchEvent(MotionEvent event) 
{

    float x = event.getRawX();
    float y = event.getRawY();
    if ( (B.getLeft() <= x <= B.getRight()) &&
         (B.getTop() <= y <= B.getBottom())
       )
    {
        Log.i("A", "Motion Event is currently above B");
        B.dispatchTouchEvent(event);
    }

    return true;
}

View Bで、同じメソッドをオーバーライドし、必ず false を返すようにします。

@Override
public boolean onTouchEvent(MotionEvent event) 
{
    //TODO handle touch event
    return false;//this will allow A to continue using the event
}
于 2012-11-19T18:27:07.477 に答える
1

ビュー A の onTouchEvent から true を返す場合、イベントは伝播されません。この特定のケースでは、A が B よりも下にある場合、ビュー A の onTouch から false が返されます。

また、コードを投稿していただけると助かります。

于 2012-11-16T04:53:51.460 に答える
0

ドラッグ アンド ドロップ フレームワークを使用してみてください。

于 2012-10-19T18:32:40.193 に答える
0

ビュー B を超えたら、それをonTouch手動で呼び出します。

if (viewBRect.contains(x, y)) {
    viewBsonTouch(view, motionEvent);
}
于 2012-11-15T12:32:47.190 に答える