11

onTouch ジェスチャonClick イベントを処理する必要があるビューがあります。これを達成する適切な方法は何ですか?

ビューにonTouchListeneronClickListenerセットがあります。ビューに触れるたびに、最初にonTouchイベントがトリガーされ、後でonClick. ただし、onTouchイベント ハンドラーからは、またはのいずれかを返すtrue必要がありfalseます。戻るtrueということは、イベントが消費されていることを意味するため、Android イベント システムはそれ以上イベントを伝播しません。

したがって、onClickイベントが生成されることはありません。少なくとも、イベントハンドラーonClickに戻ったときにリスナーがトリガーされることはありません。一方、そこに戻るオプションはありません。これにより、リスナーはジェスチャを認識するために必要なイベントをさらに受け取ることができなくなります。これを解決する通常の方法は何ですか?trueonTouchfalseonTouch

4

7 に答える 7

8

GestureDetector では、callOnClick() を直接呼び出すことができます。View.callOnClick API には API レベル 15 が必要であることに注意してください。

 // Create a Gesturedetector
GestureDetector mGestureDetector = new GestureDetector(context, new MyGestureDetector());

// Add a OnTouchListener into view
m_myViewer.setOnTouchListener(new OnTouchListener()
{

    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        return mGestureDetector.onTouchEvent(event);
    }
});

private class MyGestureDetector extends GestureDetector.SimpleOnGestureListener
{
    public boolean onSingleTapUp(MotionEvent e) {
        // ---Call it directly---
        callOnClick();
        return false;
    }

    public void onLongPress(MotionEvent e) {
    }

    public boolean onDoubleTap(MotionEvent e) {
        return false;
    }

    public boolean onDoubleTapEvent(MotionEvent e) {
        return false;
    }

    public boolean onSingleTapConfirmed(MotionEvent e) {
        return false;

    }

    public void onShowPress(MotionEvent e) {
        LogUtil.d(TAG, "onShowPress");
    }

    public boolean onDown(MotionEvent e) {            
        // Must return true to get matching events for this down event.
        return true;
    }

    public boolean onScroll(MotionEvent e1, MotionEvent e2, final float distanceX, float distanceY) {
        return super.onScroll(e1, e2, distanceX, distanceY);
    }        

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        // do something
        return super.onFling(e1, e2, velocityX, velocityY);
    }
}
于 2013-03-19T11:13:29.810 に答える
6

を使用する場合は、使用onTouchListenerする必要はありませんonClickListener。それがonClickListener行うことは、タッチイベントを取得し、イベントアクションをチェックしてクリックを検出することです。そのため、いつでも仕事をしたい場合onClickonTouchListenerアクションをフィルタリングすることで実行できます。

public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
    //this is touch

}
if (event.getAction() == MotionEvent.ACTION_UP) {
    //this is click

}
return false;
}
于 2013-01-23T13:13:20.407 に答える
4
@Override
    public boolean onTouch(View v, MotionEvent event) {


        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                layOutParams.x = initialX + (int) (event.getRawX() - initialTouchX);
                layOutParams.y = initialY + (int) (event.getRawY() - initialTouchY);

                break;
            case MotionEvent.ACTION_DOWN:
                initialX = layOutParams.x;
                initialY = layOutParams.y;
                initialTouchX = event.getRawX();
                initialTouchY = event.getRawY();
                if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) {
                    return false;// to handle Click
                }
                break;
            case MotionEvent.ACTION_UP:
                if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) {
                    return false;// to handle Click
                }
                break;

        }
        return true;

    }
};
于 2015-04-07T13:40:49.483 に答える
0

フラグベースの実装を使用できます。スワイプ/ドラッグは Action_Up で処理でき、フラグを true にして同じものを返します。クリックまたはタップの場合は、Action_Down で同じハンドルを使用し、フラグを false に設定して戻ります。

touchAndSwipe=false;
switch(e.getAction()){
    case MotionEvent.ACTION_MOVE:
        break;
    case MotionEvent.ACTION_DOWN:
        x1 = e.getX();
        break;
    case MotionEvent.ACTION_UP:
        x2 = e.getX();
        float diff = x2 - x1;
        if(Math.abs(delta) > 100) {
            // Swipe
            touchAndSwipe = true;
        } else {
            touchAndSwipe = false;
        }
        break;
}
return touchAndSwipe;
于 2015-09-01T10:33:49.703 に答える
-1

私はjdxに同意します。onTouchlistenerを使用する場合は、onclicklistenerを使用する必要はありません。ボタン、画像、またはテキストビューのクリックでイベントをトリガーする場合は、onClicklistenerを起動するだけです。ドラッグやスピンなどのアニメーションが必要な場合は、ontouchlistenerを使用してサーフェスの座標をタッチします

于 2013-01-23T13:21:42.220 に答える