[英]android - MotionEvent.ACTION_UP is never called
我想做一些工作,而用戶將手放在視圖上並在他松開時停止。 我的代碼如下:
viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(mHandler==null)
mHandler = new Handler();
mHandler.postDelayed(mAction, 500);
return true;
case MotionEvent.ACTION_UP:
Log.v("this","cancel");
if (mHandler != null) {
mHandler.removeCallbacks(mAction);
mHandler = null;
Log.v("this", "c cancel");
}
break;
}
return false;
}
Runnable mAction = new Runnable() {
@Override public void run() {
ChangeTedad(item.getid(), "plus");
Log.v("this","Cc");
mHandler.postDelayed(this, 500);
}
};
});
問題是,永遠不會調用 ACTION_UP 並且 runnable 會永遠運行。
當用戶取消觸摸時如何停止運行?
您沒有在觸摸事件中正確設置中斷和返回標志。
請替換為您的代碼,
viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(mHandler==null)
mHandler = new Handler();
mHandler.postDelayed(mAction, 500);
break;
case MotionEvent.ACTION_UP:
Log.v("this","cancel");
if (mHandler != null) {
mHandler.removeCallbacks(mAction);
mHandler = null;
Log.v("this", "c cancel");
}
break;
}
return true;
}
Runnable mAction = new Runnable() {
@Override public void run() {
ChangeTedad(item.getid(), "plus");
Log.v("this","Cc");
mHandler.postDelayed(this, 500);
}
};
});
希望這個能對您有所幫助
每當您在視圖中進行單次觸摸時,Android都會創建a series of touch events
而不是a single touch event
並緩沖這些事件,然后根據該方法返回的值順序調用onTouch
方法。
例如,當您對視圖進行一次觸摸時,正常的事件順序將是
ACTION_DOWN
(當您放下手指時) ACTION_MOVE
(如果您在觸摸屏幕時移動手指) ACTION_UP
(從屏幕上移開手指時) 但是,如果您響應ACTION_XXX
事件而從onTouchEvent
覆蓋返回false
,則不會通知您任何后續事件(您的代碼將不執行)。
回到您的情況,因為您從onTouchEvent
返回false
,所以在接收到第一個事件( ACTION_DOWN
)之后,將不調用所有后續事件(包括ACTION_UP
)。
您需要做的就是從onTouchEvent
方法返回true
。 而已!
viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mHandler == null) {
mHandler = new Handler();
}
mHandler.postDelayed(mAction, 500);
break;
case MotionEvent.ACTION_UP:
Log.v("this","cancel");
if (mHandler != null) {
mHandler.removeCallbacks(mAction);
mHandler = null;
Log.v("this", "c cancel");
}
break;
}
// [IMPORTANT] Return true here
return true;
}
Runnable mAction = new Runnable() {
@Override public void run() {
ChangeTedad(item.getid(), "plus");
Log.v("this","Cc");
mHandler.postDelayed(this, 500);
}
};
});
這是一篇非常不錯的文章,介紹了Android中的觸摸處理。 有空的時候看看吧。
您還可以將ACTION_UP邏輯代碼添加到ACTION_CANCEL ,因為如果您觸摸視圖並釋放它,它將調用ACTION_UP ,但是如果您在視圖中按下 state 並且您移動了 1 個像素,它不會調用ACTION_UP ,並且只調用ACTION_CANCEL 。 希望這對您有所幫助。
viewHolder.plus.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(mHandler==null)
mHandler = new Handler();
mHandler.postDelayed(mAction, 500);
return true;
case MotionEvent.ACTION_UP:
Log.v("this","cancel");
if (mHandler != null) {
mHandler.removeCallbacks(mAction);
mHandler = null;
Log.v("this", "c cancel");
}
break;
case MotionEvent.ACTION_CANCEL:
Log.v("this","cancel");
if (mHandler != null) {
mHandler.removeCallbacks(mAction);
mHandler = null;
Log.v("this", "c cancel");
}
break;
}
return false;
}
Runnable mAction = new Runnable() {
@Override public void run() {
ChangeTedad(item.getid(), "plus");
Log.v("this","Cc");
mHandler.postDelayed(this, 500);
}
};
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.