android 控件同時(shí)監(jiān)聽單擊和雙擊實(shí)例
不適用click而用touch
自定義監(jiān)聽:
class myOnGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDoubleTap(MotionEvent e) {
//點(diǎn)贊
mLoadingListener.onFinishedLoading("0");//取消點(diǎn)贊 是一個(gè)接口
//已經(jīng)點(diǎn)贊 更換圖片 1:已經(jīng)點(diǎn)贊 0 :沒有點(diǎn)贊
if (likeType.equals("1")){
String getLike = tvLike.getText().toString().trim();
int iL = Integer.valueOf(getLike) - 1;
tvLike.setText(String.valueOf(iL));
mIvVideolike.setImageResource(R.mipmap.video_likegray);
likeType = "0";
}else {
String getLike = tvLike.getText().toString().trim();
int iL = Integer.valueOf(getLike) + 1;
tvLike.setText(String.valueOf(iL));
mIvVideolike.setImageResource(R.mipmap.video_xin_red);
likeType = "1";
}
mRelTotal.addLoveView(e.getRawX(),e.getRawY());
return super.onDoubleTap(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (mOnVideoPlayerEventListener.isPlaying()){
mOnVideoPlayerEventListener.pause();
mIvVideoShow.setVisibility(VISIBLE);
}else {
mOnVideoPlayerEventListener.start();
mIvVideoShow.setVisibility(GONE);
}
return super.onSingleTapConfirmed(e);
}
}
使用:
myGestureDetector = new GestureDetector(mContext, new myOnGestureListener());
mRelTotal.setOnTouchListener(new View.OnTouchListener() {
@Override//可以捕獲觸摸屏幕發(fā)生的Event事件
public boolean onTouch(View v, MotionEvent event) {
//使用GestureDetector轉(zhuǎn)發(fā)MotionEvent對(duì)象給OnGestureListener
myGestureDetector.onTouchEvent(event);
return true;
}
});
補(bǔ)充知識(shí):Android 利用GestureDetector處理不太常用的一些點(diǎn)擊事件
關(guān)于GestureDetector ,在網(wǎng)上有很多資料是描述如下常見情況下的回調(diào):
點(diǎn)擊一下非常快的(不滑動(dòng))Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
點(diǎn)擊一下稍微慢點(diǎn)的(不滑動(dòng))Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
長按:
onDown-->onShowPress-->onLongPress
兩次連續(xù)點(diǎn)擊(第二次點(diǎn)擊之后立即抬起):
(第一次點(diǎn)擊)onDown->onSingleTapUp->(第二次點(diǎn)擊)onDoubleTap->onDoubleTapEvent->onDown->onShowPress->onDoubleTapEvent
點(diǎn)擊之后滑動(dòng):
onDown->onShowPress->onScroll->......(->onFling)(視速度快慢)
但是這些并不能完美符合我們的需求,我們還會(huì)遇到以下需求:
雙擊之后拖動(dòng):
我在每個(gè)回調(diào)函數(shù)打上log,雙擊之后拖動(dòng)的log如下:

(中間若干個(gè)都是onTouch: Move)

首先可以看到雙擊(onDoubleTapEvent)被回調(diào)之后的Move事件都被傳遞到了onDoubleTapEvent中。但是當(dāng)你第二次點(diǎn)擊時(shí)間達(dá)到一定之后,onLongPress會(huì)被回調(diào),而當(dāng)onLongPress被回調(diào)之后,MOVE動(dòng)作就被GestureDetector無視了,直到UP動(dòng)作出現(xiàn),顯然這不是我們想要的。
那么我們可以在onDoubleTapEvent中接收到Down動(dòng)作時(shí),利用setIsLongPressEnabled()使LongPress不會(huì)觸發(fā),然后在onDoubleTapEvent中接收到Up動(dòng)作時(shí)再恢復(fù)即可。
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
Log.d(TAG, "onDoubleTapEvent: ");
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
gestureDetector.setIsLongpressEnabled(false);
//action
break;
case MotionEvent.ACTION_MOVE:
//action
break;
case MotionEvent.ACTION_UP:
//action
gestureDetector.setIsLongpressEnabled(true);
break;
}
return true;
}
更改之后,再進(jìn)行測試,如下:

(中間若干個(gè)onTouch: Move,onDoubleTapEvent)

長按拖動(dòng):
在onLongPress被回調(diào)之后,GestureDetector不會(huì)對(duì)Move動(dòng)作調(diào)用任何函數(shù),除非直到一個(gè)Up動(dòng)作出現(xiàn),但用戶的習(xí)慣不可能是這樣。
因此對(duì)于這個(gè)需求我們需要在onTouch中對(duì)Move動(dòng)作進(jìn)行識(shí)別。
首先修改onLongPress函數(shù),在長按之后更新狀態(tài)為可拖拽,然后對(duì)onTouch中的Move動(dòng)作我們自己調(diào)用onScroll(不一定要onScroll),并且在onScroll中完成動(dòng)作,因此需要記錄上一次的MotionEvent:
@Override
public void onLongPress(MotionEvent e) {
Log.d(TAG, "onLongPress: ");
lastMotionEvent = e;
draggable = true;
}
然后在onTouch函數(shù)中:
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean result = gestureDetector.onTouchEvent(event);
// 如果gestureDetector不消費(fèi)動(dòng)作
if (!result) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
// 可拖拽狀態(tài)下調(diào)用onScroll,同時(shí)更新lastMotionEvent
if (draggable) {
onScroll(lastMotionEvent, event, lastMotionEvent.getX() - event.getX(), lastMotionEvent.getY() - event.getY());
lastMotionEvent = MotionEvent.obtain(event);
}
result = true;
break;
case MotionEvent.ACTION_UP:
// 恢復(fù)為不可拖拽狀態(tài)
if (draggable) {
onScroll(lastMotionEvent, event, lastMotionEvent.getX() - event.getX(), lastMotionEvent.getY() - event.getY());
lastMotionEvent = null;
draggable = false;
}
result = true;
break;
}
}
return result;
}
處理點(diǎn)擊-滑動(dòng)之后的ACTION_UP
滑動(dòng)的回調(diào)是這樣的
onDown->onShowPress->onScroll->......(->onFling)(視速度快慢)
如果onFling沒有被回調(diào)的話,我們無法對(duì)onScroll之后的Up動(dòng)作響應(yīng),因此對(duì)于這個(gè)動(dòng)作,我們也要在onTouch中處理。
首先要明確:
從點(diǎn)A滑動(dòng)到點(diǎn)B,并且在點(diǎn)B松手的話,在沒有觸發(fā)onFling的情況下,會(huì)回調(diào)onScroll(eA, eB, distanceX, distanceY),然后GestureDetector不消費(fèi)點(diǎn)B的Up事件,此時(shí)我們?cè)趏nTouch中處理這個(gè)Up事件。
代碼也很簡單,在長按拖動(dòng)的基礎(chǔ)上增加一個(gè)else即可:
case MotionEvent.ACTION_UP:
if (draggable) {
onScroll(lastMotionEvent, event, lastMotionEvent.getX() - event.getX(), lastMotionEvent.getY() - event.getY());
lastMotionEvent = null;
draggable = false;
} else {
afterScroll(event);
}
result = true;
break;
具體需要處理何種點(diǎn)擊事件可根據(jù)實(shí)際修改,希望分享的內(nèi)容能給你一點(diǎn)idea。
如果錯(cuò)誤,請(qǐng)指出。
以上這篇android 控件同時(shí)監(jiān)聽單擊和雙擊實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android實(shí)現(xiàn)讀取NFC卡的編號(hào)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)讀取NFC卡的編號(hào),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Android實(shí)現(xiàn)png轉(zhuǎn)jpg圖片的方法
在 Android 應(yīng)用開發(fā)中,圖像處理是非常常見的需求,本文介紹了如何在 Android平臺(tái)上實(shí)現(xiàn)一個(gè) PNG 轉(zhuǎn) JPG 的模塊,用戶可以從相冊(cè)或文件中選取 PNG 圖片,一鍵將其轉(zhuǎn)換為 JPG 并保存到本地,需要的朋友可以參考下2025-04-04
ListView的Adapter使用(綁定數(shù)據(jù)) 之 自定義每一項(xiàng)的布局去綁定數(shù)據(jù)
之前寫的綁定數(shù)據(jù)是只是簡單的綁定了字符串,這次我們將一次綁定多條數(shù)據(jù)并且嘗試用自定義的布局。在這篇文章中首先講解的是用Hashmap 去綁定數(shù)據(jù),第二個(gè)例子,講解自定義布局然后綁定數(shù)據(jù)2013-06-06
Android那兩個(gè)你碰不到但是很重要的類之ViewRootImpl
這兩個(gè)類就是ActivityThread和ViewRootImpl,之所以說碰不到是因?yàn)槲覀儫o法通過正常的方式引用這兩個(gè)類或者其類的對(duì)象,本文就嘗試從幾個(gè)我們經(jīng)常接觸的方面先談?wù)刅iewRootImpl,感興趣的可以參考閱讀下2023-05-05
關(guān)于android studio通過命令行運(yùn)行g(shù)radle編譯命令的問題
這篇文章主要介紹了關(guān)于android studio通過命令行運(yùn)行g(shù)radle編譯命令的問題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11
解析Android獲取系統(tǒng)cpu信息,內(nèi)存,版本,電量等信息的方法詳解
本篇文章對(duì)用Android獲取系統(tǒng)cpu信息,內(nèi)存,版本,電量等信息的方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05
Android RecyclerView滾動(dòng)定位
這篇文章主要為大家詳細(xì)介紹了Android RecyclerView滾動(dòng)定位的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
Kotlin協(xié)程Channel特點(diǎn)及使用細(xì)節(jié)詳解
這篇文章主要為大家介紹了Kotlin協(xié)程Channel特點(diǎn)及使用細(xì)節(jié)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12

