Идея заключается в создании Runnable
для выполнения длинного щелчка в будущем, но это выполнение может быть отменено из-за щелчка или перемещения.
Вам также необходимо знать, когда использовался длинный щелчок и когда он отменен из-за слишком большого перемещения пальца. Мы используем initialTouchX
& initialTouchY
для проверки, если пользователь выходит из квадратной области 10 пикселей, 5 с каждой стороны.
Вот мой полный код для делегирования Click & LongClick с Cell
в ListView
до Activity
с 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
}
}
}