Вот мое решение.
Для меня было важно иметь быстрое и четкое разделение «одно касание» и «двойное касание».Сначала я попробовал GestureDetector
, но результаты были очень плохими.Возможно, результат моего вложенного использования scrollviews - кто знает ...
Я сосредотачиваюсь на MotionEvent.ACTION_UP
и идентификаторе подключенного элемента.Чтобы сохранить первое нажатие, я использую Handler
, отправляющее отложенное сообщение (350 мс), чтобы у пользователя было некоторое время, чтобы поместить второе нажатие на ImageView
.Если пользователь нажал второй элемент на элемент с идентичным идентификатором, я бы назвал это двойным нажатием, удалите отложенное сообщение и присвойте мой пользовательский код «двойному касанию».Если пользователь нажал на элемент с другим идентификатором, я бы использовал его как новый и создал для него еще один Handler
.
Глобальные переменные класса
private int tappedItemId = -1;
Handler myTapHandler;
final Context ctx = this;
Пример кода
ImageView iv = new ImageView(getApplicationContext());
//[...]
iv.setId(i*1000+n);
iv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP: {
//active 'tap handler' for current id?
if(myTapHandler != null && myTapHandler.hasMessages(v.getId())) {
// clean up (to avoid single tap msg to be send and handled)
myTapHandler.removeMessages(tappedItemId);
tappedItemId = -1;
//run 'double tap' custom code
Toast.makeText(ScrollView.this, "double tap on "+v.getId(), Toast.LENGTH_SHORT).show();
return true;
} else {
tappedItemId = v.getId();
myTapHandler = new Handler(){
public void handleMessage(Message msg){
Toast.makeText(ctx, "single tap on "+ tappedItemId + " msg 'what': " + msg.what, Toast.LENGTH_SHORT).show();
}
};
Message msg = Message.obtain();
msg.what = tappedItemId;
msg.obj = new Runnable() {
public void run() {
//clean up
tappedItemId = -1;
}
};
myTouchHandler.sendMessageDelayed(msg, 350); //350ms delay (= time to tap twice on the same element)
}
break;
}
}
return true;
}
});