Android手勢(shì)處理

在和手機(jī)屏幕進(jìn)行交互的過程中,我們存在多種多樣的手勢(shì),想比如單擊,雙擊,滑動(dòng),兩指的縮放,那么Android是怎么對(duì)我們的手勢(shì)進(jìn)行監(jiān)聽的呢?通過本篇文章的學(xué)習(xí),你講對(duì)Android手勢(shì)處理有個(gè)大致的了解:
1.Android系統(tǒng)提供的手勢(shì)監(jiān)聽器OnGestureListener
2.Android系統(tǒng)提供的手勢(shì)監(jiān)聽器SimpleOnGestureListener
3.onTouchEvent自己去識(shí)別各種手勢(shì)

一.手勢(shì)監(jiān)聽器OnGestureListener

1.activity實(shí)現(xiàn)這個(gè)接口需要重寫一下方法:

    @Override
    public boolean onDown(MotionEvent motionEvent) {
        Log.i("lvv","手勢(shì)--->onDown");
        return false;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {
        Log.i("lvv","手勢(shì)--->onShowPress");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        Log.i("lvv","手勢(shì)--->onSingleTapUp");
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        Log.i("lvv","手勢(shì)--->onScroll");
        return false;
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {
        Log.i("lvv","手勢(shì)--->onLongPress");
    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        Log.i("lvv","手勢(shì)--->onFling");
        return true;
    }

這些函數(shù)在什么時(shí)候會(huì)觸發(fā):
onDown(MotionEvent motionEvent):用戶按下屏幕就會(huì)觸發(fā)
onShowPress(MotionEvent motionEvent):如果是按下的時(shí)間超過瞬間,而且在按下的時(shí)候沒有松開或者是拖動(dòng)的,那么onShowPress就會(huì)執(zhí)行,這個(gè)瞬間無法定義
onLongPress(MotionEvent e):長(zhǎng)按觸摸屏,超過一定時(shí)長(zhǎng),就會(huì)觸發(fā)這個(gè)事件
onSingleTapUp(MotionEvent motionEvent):從名子也可以看出,一次單獨(dú)的輕擊抬起操作,也就是輕擊一下屏幕,立刻抬起來,才會(huì)有這個(gè)觸發(fā),當(dāng)然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以也就不會(huì)觸發(fā)這個(gè)事件
onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1):滑屏,用戶按下觸摸屏、快速移動(dòng)后松開,由1個(gè)MotionEvent ACTION_DOWN, 多個(gè)ACTION_MOVE, 1個(gè)ACTION_UP觸發(fā)
onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1):在屏幕上拖動(dòng)事件
最后兩個(gè)方法有點(diǎn)類似,四個(gè)參數(shù)的意義也一樣:
motionEvent:第1個(gè)ACTION_DOWN MotionEvent
motionEvent1:最后一個(gè)ACTION_MOVE MotionEvent
v:X軸上的移動(dòng)速度,像素/秒
v1:Y軸上的移動(dòng)速度,像素/秒
2.創(chuàng)建手勢(shì)類,并重寫onTouchEvent方法,把onTouchEvent托管給手勢(shì)類

//創(chuàng)建手勢(shì)類并添加OnGestureListener監(jiān)聽器
GestureDetector gd=new GestureDetector(this,this);

//activity重寫方法
@Override
    public boolean onTouchEvent(MotionEvent event) {
        return gd.onTouchEvent(event);//把onTouchEvent托管給手勢(shì)類
    }

滑動(dòng)的時(shí)候會(huì)調(diào)用: onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
單擊:onDown---》onSingleTapUp
雙擊:onDown---》onSingleTapUp---》onDown---》onSingleTapUp

二.手勢(shì)監(jiān)聽器SimpleOnGestureListener

SimpleOnGestureListener手勢(shì)監(jiān)聽器相比于OnGestureListener監(jiān)聽器的優(yōu)點(diǎn)在于不需要重寫所有方法,只需要關(guān)注自己想要點(diǎn)方法即可,而且它還包含了下面OnDoubleTapListener監(jiān)聽器單雙擊的方法,因此一般情況下用這個(gè)監(jiān)聽器最好:

//創(chuàng)建手勢(shì)類添加監(jiān)聽器
GestureDetector gd=new GestureDetector(this,listener);


GestureDetector.SimpleOnGestureListener listener=new GestureDetector.SimpleOnGestureListener(){

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            return super.onSingleTapConfirmed(e);//單擊
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return super.onDoubleTap(e);//雙擊
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return super.onFling(e1, e2, velocityX, velocityY);
        }
    };

同時(shí),有一個(gè)OnDoubleTapListener是只需要關(guān)注單擊和雙擊事件的:

//創(chuàng)建手勢(shì)類添加監(jiān)聽器
GestureDetector gd=new GestureDetector(this,this);
gd.setOnDoubleTapListener(listener2);//手勢(shì)類添加OnDoubleTapListener監(jiān)聽器

//activity重寫方法
@Override
    public boolean onTouchEvent(MotionEvent event) {
        return gd.onTouchEvent(event);//把onTouchEvent托管給手勢(shì)類
    }
GestureDetector.OnDoubleTapListener listener2=new GestureDetector.OnDoubleTapListener() {
        @Override
        public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
            Log.i("lvv","手勢(shì)---》onSingleTapConfirmed");//單擊事件
            return false;
        }

        @Override
        public boolean onDoubleTap(MotionEvent motionEvent) {
            Log.i("lvv","手勢(shì)---》onDoubleTap");//雙擊事件
            return true;
        }

        @Override
        public boolean onDoubleTapEvent(MotionEvent motionEvent) {
            Log.i("lvv","手勢(shì)---》onDoubleTapEvent");
            return false;
        }
    };

三.onTouchEvent自己識(shí)別

可以通過重寫onTouchEvent方法獲取event.getAction()得到手指的狀態(tài),按下,移動(dòng),抬起,判斷是一根手指的時(shí)候就是拖動(dòng)狀態(tài),可以用于模仿微信拖動(dòng)圖片拖動(dòng)到下方然后消失,判斷是兩根手指的時(shí)候就是縮放狀態(tài),用于模仿微信雙手縮放圖片根據(jù)判斷兩根手指的距離是增加還是減少進(jìn)行放大和縮小。

private int currentStatus=STATUS_INIT;//當(dāng)前的狀態(tài)
    
    public static final int STATUS_INIT = 1;//初始化的狀態(tài)

    public static final int STATUS_ZOOM_OUT = 2;//圖片放大狀態(tài)常量

    public static final int STATUS_ZOOM_IN = 3;//圖片縮小狀態(tài)常量

    public static final int STATUS_MOVE = 4;//圖片拖動(dòng)狀態(tài)常量

    private float xMove = -1;//記錄當(dāng)前手指的橫坐標(biāo)
    private float lastXMove = -1;//記錄上次手指移動(dòng)時(shí)的橫坐標(biāo)

    private float yMove = -1;//記錄當(dāng)前手指的縱坐標(biāo)
    private float lastYMove = -1;//記錄上次手指移動(dòng)時(shí)的縱坐標(biāo)

    private double lastFingerDis;//記錄上次兩指之間的距離
    private double fingerDis;//記錄當(dāng)前兩指之間的距離

    private float scaledRatio;//記錄手指移動(dòng)的距離所造成的縮放比例
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_POINTER_DOWN:
                if (event.getPointerCount() == 2) {
                    // 當(dāng)有兩個(gè)手指按在屏幕上時(shí),計(jì)算兩指之間的距離
                    lastFingerDis = distanceBetweenFingers(event);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (event.getPointerCount() == 1) {
                    // 只有單指按在屏幕上移動(dòng)時(shí),為拖動(dòng)狀態(tài)
                     xMove = event.getX();
                     yMove = event.getY();
                    if (lastXMove == -1 && lastYMove == -1) {
                        lastXMove = xMove;
                        lastYMove = yMove;
                    }
                    currentStatus = STATUS_MOVE;
                    // ------------拖動(dòng)數(shù)值----------------
                    //after(xMove,yMove),befor(lastXMove,lastYMove)
                    lastXMove = xMove;
                    lastYMove = yMove;

                } else if (event.getPointerCount() == 2) {
                    // 有兩個(gè)手指按在屏幕上移動(dòng)時(shí),為縮放狀態(tài)
                     fingerDis = distanceBetweenFingers(event);
                    if (fingerDis > lastFingerDis) {
                        currentStatus = STATUS_ZOOM_OUT;
                    } else {
                        currentStatus = STATUS_ZOOM_IN;
                    }
                    // ------------縮放倍數(shù)----------------
                    scaledRatio = (float) (fingerDis / lastFingerDis);
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                if (event.getPointerCount() == 2) {
                    // 手指離開屏幕時(shí)將臨時(shí)值還原
                    lastXMove = -1;
                    lastYMove = -1;
                }
                break;
            case MotionEvent.ACTION_UP:
                // 手指離開屏幕時(shí)將臨時(shí)值還原
                lastXMove = -1;
                lastYMove = -1;
                break;
            default:
                break;
        }
        return true;
    }

    /**
     * 計(jì)算兩個(gè)手指之間的距離。
     *
     * @param event
     * @return 兩個(gè)手指之間的距離
     */
    private double distanceBetweenFingers(MotionEvent event) {
        float disX = Math.abs(event.getX(0) - event.getX(1));
        float disY = Math.abs(event.getY(0) - event.getY(1));
        return Math.sqrt(disX * disX + disY * disY);
    }

四.總結(jié)

以上就是關(guān)于Android手勢(shì)處理的相關(guān)知識(shí)點(diǎn),如有不足或者錯(cuò)誤的地方請(qǐng)?jiān)谙路街刚?。我們需要多看更需要多寫,只有不斷學(xué)習(xí),不斷進(jìn)步才能不被淘汰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 手勢(shì)處理有兩種中:觸摸和手勢(shì)處理; 觸摸適合簡(jiǎn)單的情況:按下,抬起,移動(dòng),取消,移除邊界。 @Overridepu...
    沈鳳德閱讀 1,217評(píng)論 0 1
  • 1.GestureDetector手勢(shì)檢測(cè)器 在onTouch中收到的MotionEvent我們可以拿到時(shí)間的類型...
    ztzt123閱讀 450評(píng)論 0 0
  • View的事件體系 View的基礎(chǔ) view位置參數(shù)View的位置主要由它的四個(gè)頂點(diǎn)來決定,分別對(duì)應(yīng)于View的四...
    MZzF2HC閱讀 583評(píng)論 0 2
  • 前言 Android提供了一個(gè)GestureDetector來幫助我們識(shí)別一些基本的觸摸手勢(shì)(還有ScaleGes...
    zerohdq閱讀 2,880評(píng)論 1 0
  • 這幾天因?yàn)楣ぷ髟蚪佑|了一批90后的年輕人,他們喜歡新潮時(shí)尚的穿衣風(fēng)格,喜歡名牌,喜歡吃網(wǎng)紅店,喜歡到處去玩。 但...
    芳療女王閱讀 118評(píng)論 0 0

友情鏈接更多精彩內(nèi)容