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
長(zhǎng)按:
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)行測(cè)試,如下:
(中間若干個(gè)onTouch: Move,onDoubleTapEvent)
長(zhǎng)按拖動(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ù),在長(zhǎng)按之后更新狀態(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事件。
代碼也很簡(jiǎn)單,在長(zhǎng)按拖動(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í)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
簡(jiǎn)單實(shí)現(xiàn)Android本地音樂播放器
這篇文章主要為大家詳細(xì)介紹了如何簡(jiǎn)單實(shí)現(xiàn)Android本地音樂播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Android studio 實(shí)現(xiàn)隨機(jī)位置畫10個(gè)隨機(jī)大小的五角星的代碼
這篇文章主要介紹了Android studio 實(shí)現(xiàn)隨機(jī)位置畫10個(gè)隨機(jī)大小的五角星,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05Android將項(xiàng)目導(dǎo)出為L(zhǎng)ibrary并在項(xiàng)目中使用教程
這篇文章主要介紹了Android將項(xiàng)目導(dǎo)出為L(zhǎng)ibrary并在項(xiàng)目中使用教程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07Android Studio使用recyclerview實(shí)現(xiàn)展開和折疊功能(在之前的微信頁(yè)面基礎(chǔ)之上)
這篇文章主要介紹了Android Studio使用recyclerview實(shí)現(xiàn)展開和折疊(在之前的微信頁(yè)面基礎(chǔ)之上),本文通過截圖實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2020-03-03Android編程之九宮格實(shí)現(xiàn)方法實(shí)例分析
這篇文章主要介紹了Android編程之九宮格實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Android九宮格的實(shí)現(xiàn)方法與具體步驟,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-01-01Android自定義ViewGroup之第一次接觸ViewGroup
這篇文章主要為大家詳細(xì)介紹了Android自定義ViewGroup之第一次接觸ViewGroup,感興趣的小伙伴們可以參考一下2016-06-06flutter InkWell實(shí)現(xiàn)水波紋點(diǎn)擊效果
這篇文章主要為大家詳細(xì)介紹了flutter InkWell實(shí)現(xiàn)水波紋點(diǎn)擊效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07DownloadManager實(shí)現(xiàn)文件下載功能
這篇文章主要為大家詳細(xì)介紹了DownloadManager實(shí)現(xiàn)文件下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11