015-Android自定义View(10):手势监听&处理

1,773 阅读2分钟

1.基础

了解自定义view事件分发处理机制,请参考Android自定义View(9):事件分发&处理


2. 手势简介

  1. GestureDetector是手势监听类,能够监听手指接触屏幕后的一系列动作:按下、短按、长按、滑动、单指抬起等;

  2. ScaleGestureDetector是缩放手势监听类,能够监听多指缩放事件,用法与GestureDetector基本一致;

  3. GestureDetector有两个监听接口,分别是OnGestureListener,OnDoubleTapListener,分别在构造函数中、setOnDoubleTapListener()设置,用于获取对应事件序列回调;

  4. 长按手势需单独设置开启监听,才会回调对应事件方法:mGestureDetector.setIsLongpressEnabled(true)

  5. 缩放手势一般只处理onScale()

3. GestureDetector使用三部曲

具体用法解释及注意点请看代码备注

3.1初始化

在需要监听手势的View 或者 Activity中,声明对象、初始化

//1.声明
GestureDetector mGestureDetector;
//2.初始化
mGestureDetector = new GestureDetector(this ,this);
mGestureDetector.setOnDoubleTapListener(this);
mGestureDetector.setIsLongpressEnabled(true);//允许长按
//3.对应的类实现接口GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener
...

3.2触摸事件交接

//重写View或Activity的onTouchEvent()
@Override
public boolean onTouchEvent(MotionEvent event) {
    mGestureDetector.onTouchEvent(event);
    return true;
}

3.3接口回调方法中实现需求功能

//===============================================================================
//=========================== OnDoubleTapListener的方法回调 =========================
//===============================================================================
    @Override
    public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
        Log.e(TAG, "onSingleTapConfirmed " );
        mTvStatus.append("单击事件\n");
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent motionEvent) {
        Log.e(TAG, "onDoubleTap: " );
        mTvStatus.append("双击事件\n");
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent motionEvent) {
        Log.e(TAG, "onDoubleTapEvent: " );
        //双击间隔中间的event回调
        return true;
    }
//===============================================================================
//=========================== OnGestureListener的方法回调 =========================
//===============================================================================
    @Override
    public boolean onDown(MotionEvent motionEvent) {
        Log.e(TAG, "onDown: " );
        mTvStatus.append("====================\n");
        mTvStatus.append("序列事件:按下\n");
        return true;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {
        Log.e(TAG, "onShowPress: " );
        mTvStatus.append("序列事件:短按屏幕\n");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        Log.e(TAG, "onSingleTapUp: " );
        mTvStatus.append("序列事件:单指抬起\n");
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        Log.e(TAG, "onScroll: " );
        mTvStatus.append("序列事件:手指滑动\n");
        return false;
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {
        Log.e(TAG, "onLongPress: " );
        mTvStatus.append("序列事件:长按\n");
    }

    // velocityX:X轴方向速度,单位px/s
    // velocityY:Y轴方向速度,单位px/s
    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float velocityX, float velocityY) {
        Log.e(TAG, "onFling: " );
        mTvStatus.append("序列事件:手指划飞\n");
        return true;
    }

4.ScaleGestureDetector使用

具体细节&主要要点留意代码注释

4.1初始化

    //1.声明
    ScaleGestureDetector mScaleGestureDetector;
    //2.初始化
    mScaleGestureDetector = new ScaleGestureDetector(this ,this);
    //3.所在对应类实现接口OnScaleGestureListener

4.2事件交接

  @Override
    public boolean onTouchEvent(MotionEvent event) {
        mGestureDetector.onTouchEvent(event);
        mScaleGestureDetector.onTouchEvent(event);
        return true;
    }

4.3回调处理


//===============================================================================
//=========================== OnScaleGestureListener的方法回调 =========================
//===============================================================================
    @Override
    public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
        Log.e(TAG, "onScale: " );
        mTvStatus.append("序列事件:缩放ing\n");
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
        Log.e(TAG, "onScaleBegin: " );
        mTvStatus.append("序列事件:缩放begin\n");
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
        Log.e(TAG, "onScaleEnd: " );
        mTvStatus.append("序列事件:缩放end\n");
    }

5.实践

手势监听&处理的最佳实践:实现自定义ImageView

  1. 双指缩放
  2. 拖拽移动
  3. 点击事件回调(查看大图的Activity中可以finish)
  4. 双击事件回调,图片复原

6.布局等其他代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:id="@+id/tv_status"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="手势监听"
        />

</RelativeLayout>