84

私は現在使用しています

onTouchEvent(MotionEvent event){
}

ユーザーが私の glSurfaceView を押したときを検出するには、長いクリックが行われたときを検出する方法があります。開発ドキュメントであまり見つけられない場合は、何らかの回避策になると思います。ACTION_DOWN を登録して、ACTION_UP までの時間を確認するようなものです。

opengl-esを使用してAndroidで長押しを検出するにはどうすればよいですか?

4

11 に答える 11

164

GestureDetectorが最適なソリューションです。

ここに興味深い代替案があります。onTouchEventでは、すべてのACTION_DOWNスケジュールで Runnable を 1 秒で実行します。ACTION_UPまたはACTION_MOVEごとに、スケジュールされた Runnable をキャンセルします。ACTION_DOWNイベントから 1 秒以内にキャンセルが発生した場合、Runnable は実行されません。

final Handler handler = new Handler(); 
Runnable mLongPressed = new Runnable() { 
    public void run() { 
        Log.i("", "Long press!");
    }   
};

@Override
public boolean onTouchEvent(MotionEvent event, MapView mapView){
    if(event.getAction() == MotionEvent.ACTION_DOWN)
        handler.postDelayed(mLongPressed, ViewConfiguration.getLongPressTimeout());
    if((event.getAction() == MotionEvent.ACTION_MOVE)||(event.getAction() == MotionEvent.ACTION_UP))
        handler.removeCallbacks(mLongPressed);
    return super.onTouchEvent(event, mapView);
}
于 2012-07-27T00:07:35.363 に答える
118

これを試して:

final GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
    public void onLongPress(MotionEvent e) {
        Log.e("", "Longpress detected");
    }
});

public boolean onTouchEvent(MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
};
于 2011-10-27T19:42:42.670 に答える
3

ユーザーのプレスとは、クリックのことですか? クリックとは、ユーザーが指を押し下げてからすぐに指を離すことです。したがって、2 つの onTouch イベントが含まれています。最初のタッチまたはリリース後に発生するものについては、 onTouchEvent の使用を保存する必要があります。

したがって、クリックの場合は onClickListener を使用する必要があります。

あなたの答えは類似しています:onLongClickListenerを使用してください。

于 2011-10-27T18:45:11.807 に答える
1

アイデアはRunnable、将来的に長いクリックを実行するためのものですが、この実行はクリックまたは移動のためにキャンセルされる可能性があります。

また、ロング クリックが消費されたタイミングと、指が動きすぎてキャンセルされたタイミングも把握する必要があります。initialTouchX&を使用initialTouchYして、ユーザーが 10 ピクセル (各辺 5 ピクセル) の正方形の領域から出たかどうかを確認します。

Click と LongClickCellinListViewからActivitywithに委任するための完全なコードを次に示しOnTouchListenerます。

    ClickDelegate delegate; 
    boolean goneFlag = false;
    float initialTouchX;
    float initialTouchY;
    final Handler handler = new Handler();
    Runnable mLongPressed = new Runnable() {
        public void run() {
            Log.i("TOUCH_EVENT", "Long press!");
            if (delegate != null) {
                goneFlag = delegate.onItemLongClick(index);
            } else {
                goneFlag = true;
            }
        }
    };

    @OnTouch({R.id.layout})
    public boolean onTouch (View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                handler.postDelayed(mLongPressed, ViewConfiguration.getLongPressTimeout());
                initialTouchX = motionEvent.getRawX();
                initialTouchY = motionEvent.getRawY();
                return true;
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_CANCEL:
                if (Math.abs(motionEvent.getRawX() - initialTouchX) > 5 || Math.abs(motionEvent.getRawY() - initialTouchY) > 5) {
                    handler.removeCallbacks(mLongPressed);
                    return true;
                }
                return false;
            case MotionEvent.ACTION_UP:
                handler.removeCallbacks(mLongPressed);
                if (goneFlag || Math.abs(motionEvent.getRawX() - initialTouchX) > 5 || Math.abs(motionEvent.getRawY() - initialTouchY) > 5) {
                    goneFlag = false;
                    return true;
                }
                break;
        }
        Log.i("TOUCH_EVENT", "Short press!");
        if (delegate != null) {
            if (delegate.onItemClick(index)) {
                return false;
            }
        }
        return false;
    }

ClickDelegateinterfaceのようなハンドラ クラスにクリック イベントを送信するためのActivity

    public interface ClickDelegate {
        boolean onItemClick(int position);
        boolean onItemLongClick(int position);
    }

そして、動作を委任する必要がある場合は、それを自分Activityまたは親に実装するだけで済みます。View

public class MyActivity extends Activity implements ClickDelegate {

    //code...
    //in some place of you code like onCreate, 
    //you need to set the delegate like this:
    SomeArrayAdapter.delegate = this;
    //or:
    SomeViewHolder.delegate = this;
    //or:
    SomeCustomView.delegate = this;

    @Override
    public boolean onItemClick(int position) {
        Object obj = list.get(position);
        if (obj) {
            return true; //if you handle click
        } else {
            return false; //if not, it could be another event
        }
    }

    @Override
    public boolean onItemLongClick(int position) {
        Object obj = list.get(position);
        if (obj) {
            return true; //if you handle long click
        } else {
            return false; //if not, it's a click
        }
    }
}
于 2018-05-16T15:58:22.197 に答える
0
setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {

                int action = MotionEventCompat.getActionMasked(event);


                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        longClick = false;
                        x1 = event.getX();
                        break;

                    case MotionEvent.ACTION_MOVE:
                        if (event.getEventTime() - event.getDownTime() > 500 && Math.abs(event.getX() - x1) < MIN_DISTANCE) {
                            longClick = true;
                        }
                        break;

                    case MotionEvent.ACTION_UP:
                                if (longClick) {
                                    Toast.makeText(activity, "Long preess", Toast.LENGTH_SHORT).show();
                                } 
                }
                return true;
            }
        });
于 2016-03-27T04:32:08.153 に答える
-3

私は1つの解決策を見つけました.runnableやその他のものを定義する必要はなく、うまく機能しています。

    var lastTouchTime: Long = 0

    // ( ViewConfiguration.#.DEFAULT_LONG_PRESS_TIMEOUT =500)
    val longPressTime = 500

    var lastTouchX = 0f
    var lastTouchY = 0f

    view.setOnTouchListener { v, event ->

        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                lastTouchTime = SystemClock.elapsedRealtime()
                lastTouchX = event.x
                lastTouchY = event.y
                return@setOnTouchListener true
            }
            MotionEvent.ACTION_UP -> {
                if (SystemClock.elapsedRealtime() - lastTouchTime > longPressTime
                        && Math.abs(event.x - lastTouchX) < 3
                        && Math.abs(event.y - lastTouchY) < 3) {
                    Log.d(TAG, "Long press")
                }
                return@setOnTouchListener true
            }
            else -> {
                return@setOnTouchListener false
            }
        }

    }
于 2019-07-17T05:48:02.667 に答える