1

GestureDetectorからコードを借用して長押しを実装しようとすると、onTouchEvent()がtrueを返したときにGestureHandlerでメッセージを受信しない最小限のサンプルに到達しました。falseを返すと、メッセージは配信されますが、イベント処理は終了し、長押しはキャンセルされません。

onTouchEvent()がtrueを返すようにこのコードを機能させる方法はありますか?

public class OverlayView extends View  {
    private static final int LONG_PRESS = 1;
    private Handler handler;
    private static final String TAG = OverlayView.class.getName();
    private class GestureHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case LONG_PRESS:
                dispatchLongPress();
                break;

            default:
                throw new RuntimeException("Unknown message " + msg);
            }
        }
    }

    public OverlayView(Context context, AttributeSet attrs) {
        super(context, attrs);
        handler = new GestureHandler();
    }

    private void dispatchLongPress() {
        Toast.makeText(getContext(), "Long Press", Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        Log.d(TAG, e.toString());
        switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            handler.removeMessages(LONG_PRESS);          
            handler.sendEmptyMessageAtTime(LONG_PRESS, e.getDownTime() + 1000);
            break;
        case MotionEvent.ACTION_MOVE:
            handler.removeMessages(LONG_PRESS);
            break;
        case MotionEvent.ACTION_UP:
            handler.removeMessages(LONG_PRESS);
            break;
        default:
            break;
        }

        return true;
    }
}
4

1 に答える 1

1

非常に安定したハンドを持っている場合でも、ACTION_MOVEイベントを作成する可能性があります。

case MotionEvent.ACTION_MOVE:
    handler.removeMessages(LONG_PRESS);
    break;

指は数ピクセルしか動かしませんが、長押しのコールバックを取り除くにはこれで十分です。

Android は、いくつかの静的変数ラベルを使用して、最初のイベントと現在のイベントの___SLOP間の距離を計算します。ACTION_DOWNMotionEvent がスロップしきい値を超えると、コールバックがキャンセルされます。同じアプローチを使用することをお勧めします。

于 2012-12-10T18:00:19.203 に答える