私は現在使用しています
onTouchEvent(MotionEvent event){
}
ユーザーが私の glSurfaceView を押したときを検出するには、長いクリックが行われたときを検出する方法があります。開発ドキュメントであまり見つけられない場合は、何らかの回避策になると思います。ACTION_DOWN を登録して、ACTION_UP までの時間を確認するようなものです。
opengl-esを使用してAndroidで長押しを検出するにはどうすればよいですか?
私は現在使用しています
onTouchEvent(MotionEvent event){
}
ユーザーが私の glSurfaceView を押したときを検出するには、長いクリックが行われたときを検出する方法があります。開発ドキュメントであまり見つけられない場合は、何らかの回避策になると思います。ACTION_DOWN を登録して、ACTION_UP までの時間を確認するようなものです。
opengl-esを使用してAndroidで長押しを検出するにはどうすればよいですか?
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);
}
これを試して:
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);
};
ユーザーのプレスとは、クリックのことですか? クリックとは、ユーザーが指を押し下げてからすぐに指を離すことです。したがって、2 つの onTouch イベントが含まれています。最初のタッチまたはリリース後に発生するものについては、 onTouchEvent の使用を保存する必要があります。
したがって、クリックの場合は onClickListener を使用する必要があります。
あなたの答えは類似しています:onLongClickListenerを使用してください。
アイデアはRunnable
、将来的に長いクリックを実行するためのものですが、この実行はクリックまたは移動のためにキャンセルされる可能性があります。
また、ロング クリックが消費されたタイミングと、指が動きすぎてキャンセルされたタイミングも把握する必要があります。initialTouchX
&を使用initialTouchY
して、ユーザーが 10 ピクセル (各辺 5 ピクセル) の正方形の領域から出たかどうかを確認します。
Click と LongClickをCell
inListView
からActivity
withに委任するための完全なコードを次に示し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;
}
ClickDelegate
interface
のようなハンドラ クラスにクリック イベントを送信するための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
}
}
}
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;
}
});
私は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
}
}
}