安卓应知应会的手势操作GestureDetector

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

前言

Android开发过程中,难免会遇到使用手势,大部分的解决方案都是通过对View的Onclick事件或者onTouch事件做处理,其实Android是有自带的手势操作封装类GestureDetector,可以监听手势的操作,来处理手势操作,比如Scroll手势在浏览器中个滚屏,Fling在浏览器中的换页等! 当然,有利也有弊,比如不当的手势操作引起APP Carsh,经常这样可是会引起用户不满的! 所以是否要为你的应用增加手势,可要考虑清楚哦

一、GestureDetector介绍

GestureDetector这个类对外提供了两个接口和一个外部类

  • 接口:OnGestureListener,OnDoubleTapListener
  • 内部类:SimpleOnGestureListener

GestureDetector类介绍

private class Gesturelistener implements GestureDetector.OnGestureListener{ 
public boolean onDown(MotionEvent e) { 
// TODO Auto-generated method stub 
return false; 
} 
public void onShowPress(MotionEvent e) { 
// TODO Auto-generated method stub 
} 
public boolean onSingleTapUp(MotionEvent e) { 
// TODO Auto-generated method stub 
return false; 
} 
public boolean onScroll(MotionEvent e1, MotionEvent e2, 
float distanceX, float distanceY) { 
// TODO Auto-generated method stub 
return false; 
} 
public void onLongPress(MotionEvent e) { 
// TODO Auto-generated method stub 
} 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
float velocityY) { 
// TODO Auto-generated method stub 
return false; 
} 
} 
复制代码

这里总共重写了六个函数

1、OnDown(MotionEvent e):用户按下屏幕就会触发;

2、onShowPress(MotionEvent e):如果是按下的时间超过瞬间,而且在按下的时候没有松开或者是拖动的,那么onShowPress就会执行

3、onLongPress(MotionEvent e):长按触摸屏,超过一定时长,就会触发这个事件,触发顺序:onDown->onShowPress->onLongPress

4、onSingleTapUp(MotionEvent e):一次单独的轻击抬起操作,也就是轻击一下屏幕,立刻抬起来,才会有这个触发,当然,如果除了Down以外还有其它操作,那就不再算是Single操作了,所以也就不会触发这个事件;触发顺序:Touchup:onDown->onSingleTapUp->onSingleTapConfirmed ;

5.onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) :滑屏,用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发;

参数解释:

  • e1:第1个ACTION_DOWN MotionEvent
  • e2:最后一个ACTION_MOVE MotionEvent
  • velocityX:X轴上的移动速度,像素/秒
  • velocityY:Y轴上的移动速度,像素/秒

6、onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY):在屏幕上拖动事件;无论是用手拖动view,或者是以抛的动作滚动,都会多次触发,这个方法在ACTION_MOVE动作发生时就会触发;

扫描二维码关注公众号,回复: 13283047 查看本文章

滑屏:手指触动屏幕后,稍微滑动后立即松开

onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling

拖动

onDown------》onScroll----》onScroll------》onFiling

无论是滑屏,还是拖动,影响的只是中间OnScroll触发的数量多少而已,最终都会触发onFling事件;

二、实现GestureDetector

1、实现OnGestureListener接口中的方法(可以使用匿名内部类或实现了接口的类实例);

class MyGestureListener implements GestureDetector.OnGestureListener { 
    @Override 
    public boolean onDown(MotionEvent e) { 
        return false; 
    } 
    @Override 
    public void onShowPress(MotionEvent e) { 
    } 
    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
        return false; 
    } 
    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
        return false; 
    } 
    @Override 
    public void onLongPress(MotionEvent e) { 
    } 
    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
        return false; 
    } 
} 
复制代码

2、创建GestureDetector类的实例,构造函数如下:

public GestureDetector(OnGestureListener listener, Handler handler) { 
    this(null, listener, handler); 
} 
public GestureDetector(OnGestureListener listener) { 
    this(null, listener, null); 
} 
public GestureDetector(Context context, OnGestureListener listener) { 
    this(context, listener, null); 
} 
public GestureDetector(Context context, OnGestureListener listener, Handler handler) { 
} 
public GestureDetector(Context context, OnGestureListener listener, Handler handler, 
        boolean unused) { 
    this(context, listener, handler); 
} 
mGestureDetector = new GestureDetector(mContext,new MyGestureListener()); 
复制代码

3、 实现View.OnTouchListener接口,重写onTouch()方法

4、在onTouch()方法中拦截事件处理,将控制权交给GestureDector;

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    return mGestureDetector.onTouchEvent(event); 
} 
复制代码

5、调用控件的View.setOnTouchListener()将接口的具体实现的引用传递进去或者如果是监听双击的话调用GestureDetector .setOnDoubleTapListener()

下面简单写个手势操作和使用的例子:

OnGestureListener:

public class MainActivity extends AppCompatActivity {

    private MyGestureListener mgListener;
    private GestureDetector mDetector;
    private final static String TAG = "MyGesture";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化GestureListener与GestureDetector对象
        mgListener = new MyGestureListener();
        mDetector = new GestureDetector(this, mgListener);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mDetector.onTouchEvent(event);
    }

    //自定义一个GestureListener,这个是View类下的,别写错哦!!!
    private class MyGestureListener implements GestureDetector.OnGestureListener {

        @Override
        public boolean onDown(MotionEvent motionEvent) {
            Log.d(TAG, "onDown:按下");
            return false;
        }

        @Override
        public void onShowPress(MotionEvent motionEvent) {
            Log.d(TAG, "onShowPress:手指按下一段时间,不过还没到长按");
        }

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {
            Log.d(TAG, "onSingleTapUp:手指离开屏幕的一瞬间");
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            Log.d(TAG, "onScroll:在触摸屏上滑动");
            return false;
        }

        @Override
        public void onLongPress(MotionEvent motionEvent) {
            Log.d(TAG, "onLongPress:长按并且没有松开");
        }

        @Override
        public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
            Log.d(TAG, "onFling:迅速滑动,并松开");
            return false;
        }
    }

}
复制代码

SimpleOnGestureListener:

public class MainActivity extends AppCompatActivity {

    private GestureDetector mDetector;
    private final static int MIN_MOVE = 200;   //最小距离
    private MyGestureListener mgListener;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化SimpleOnGestureListener与GestureDetector对象
        mgListener = new MyGestureListener();
        mDetector = new GestureDetector(this, mgListener);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mDetector.onTouchEvent(event);
    }

    //自定义一个GestureListener,这个是View类下的,别写错哦!!!
    private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float v, float v1) {
            if(e1.getY() - e2.getY() > MIN_MOVE){
                startActivity(new Intent(MainActivity.this, MainActivity.class));
                Toast.makeText(MainActivity.this, "通过手势启动Activity", Toast.LENGTH_SHORT).show();
            }else if(e1.getY() - e2.getY()  < MIN_MOVE){
                finish();
                Toast.makeText(MainActivity.this,"通过手势关闭Activity",Toast.LENGTH_SHORT).show();
            }
            return true;
        }
    }

}
复制代码

相比较OnGestureListener监听来说,SimpleOnGestureListener 使用起来笔记简单,想重写什么方法就重写什么方法

自定义GesturerListenerView

public class MyGestureDetectorView extends View implements View.OnTouchListener{ 
    private Context mContext; 
    private GestureDetector mGestureDetector; 
    private static final String TAG = "MyView"; 
    public MyGestureDetectorView(Context context) { 
        super(context); 
        initData(context); 
    } 
    public MyGestureDetectorView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        initData(context); 
    } 
    public MyGestureDetectorView(Context context, AttributeSet attrs, int defStyleAttr) { 
        super(context, attrs, defStyleAttr); 
        initData(context); 
    } 
    private void initData(Context context) { 
        this.mContext = context; 
        super.setOnTouchListener(this); 
        super.setClickable(true); 
        super.setLongClickable(true); 
        super.setFocusable(true); 
        mGestureDetector = new GestureDetector(mContext,new MyGestureListener()); 
        mGestureDetector.setOnDoubleTapListener(new MyGestureListener()); 
    } 
    /* 
     * 当该view上的事件被分发到view上时触发该方法的回调 
     * 如果这个方法返回false时,该事件就会被传递给Activity中的onTouchEvent方法来处理 
     * 如果该方法返回true时,表示该事件已经被onTouch函数处理玩,不会上传到activity中处理 
     * 该方法属于View.OnTouchListening接口 
     */ 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
        return mGestureDetector.onTouchEvent(event); 
    } 
    /* 
     * 手势监听类 
     */ 
    class MyGestureListener extends GestureDetector.SimpleOnGestureListener { 
        public MyGestureListener() { 
            super(); 
        } 
        @Override 
        public boolean onDoubleTap(MotionEvent e) { 
            Log.e(TAG, "onDoubleTap"); 
            return true; 
        } 
        @Override 
        public boolean onDoubleTapEvent(MotionEvent e) { 
            Log.e(TAG, "onDoubleTapEvent"); 
            return true; 
        } 
        @Override 
        public boolean onSingleTapConfirmed(MotionEvent e) { 
            Log.e(TAG, "onSingleTapConfirmed"); 
            return true; 
        } 
        @Override 
        public boolean onContextClick(MotionEvent e) { 
            Log.e(TAG, "onContextClick"); 
            return true; 
        } 
        @Override 
        public boolean onDown(MotionEvent e) { 
            Log.e(TAG, "onDown"); 
            return true; 
        } 
        @Override 
        public void onShowPress(MotionEvent e) { 
            Log.e(TAG, "onShowPress"); 
        } 
        @Override 
        public boolean onSingleTapUp(MotionEvent e) { 
            Log.e(TAG, "onSingleTapUp"); 
            return true; 
        } 
        @Override 
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
            Log.e(TAG, "onScroll"); 
            return true; 
        } 
        @Override 
        public void onLongPress(MotionEvent e) { 
            Log.e(TAG, "onLongPress"); 
        } 
        @Override 
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
            Log.e(TAG, "onFling"); 
            return true; 
        } 
    } 
复制代码

自定义控件继承了View实现了View.OnTouchListener。监听的方法用的是继承SimpleOnGestureListener类,重写了所有方法;

总结

这就是android 的手势操作监听使用方法,用起来比较简单,你会用了么?

猜你喜欢

转载自juejin.im/post/7032900181519515685