GestureDetector这个类对外提供了两个接口和一个外部类
接口:OnGestureListener,OnDoubleTapListener
:第一个接口处理手势,第二个接口 处理 单击或者双击
内部类:SimpleOnGestureListene
: 这个外部类 就是 接口中的所有函数的集成,他包含了这两个接口里所有需要实现的函数,并且进行了重写,但是所有的方法体都是空的;该类是 static class ,程序员可以在外部继承这个类,重写里面的手势 方法。
1,使用接口
使用如下:
public class GestureListener implements GestureDetector.OnGestureListener , GestureDetector.OnDoubleTapListener{ private static final String TAG = "GestureListener"; // 用户按下屏幕就会触发; @Override public boolean onDown(MotionEvent e) { Log.e(TAG, "onDown: 按下屏幕就会触发" ); return false; } //用户按下屏幕,尚未松开或 者拖动 则会触发 @Override public void onShowPress(MotionEvent e) { Log.e(TAG, "onShowPress: 按下屏幕,尚未松开或 者拖动" ); } // 用户点击屏幕后松开,则会触发该事件 @Override public boolean onSingleTapUp(MotionEvent e) { Log.e(TAG, "onSingleTapUp: 点击屏幕后松开" ); return false; } /** * 用户按下屏幕,并拖动 * @param distanceX x 轴滑动距离 * @param distanceY y 轴滑动距离 */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.e(TAG, "onScroll: 用户按下屏幕,并拖动" ); return false; } // 用户长按屏幕, @Override public void onLongPress(MotionEvent e) { Log.e(TAG, "onLongPress:长按屏幕 " ); } /** * 用户按下屏幕,快速移动后松开, * @param e1 按下的 event * @param e2 抬起的 event * @param velocityX x 轴上的移动速度 像素 每秒 * @param velocityY y 轴上的移动速度 像素 每秒 */ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.e(TAG, "onFling: 用户按下屏幕,快速移动后松开," ); return false; } //单击事件, @Override public boolean onSingleTapConfirmed(MotionEvent e) { Log.e(TAG, "onSingleTapConfirmed: 点击" ); return false; } // 双击 事件 @Override public boolean onDoubleTap(MotionEvent e) { Log.e(TAG, "onDoubleTap: 双击" ); return false; } // 双击 间隔中发生的动作 @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.e(TAG, "onDoubleTapEvent: 双击中的间隔" ); return false; } }
上面实现了 两个接口 重写了所有的方法,注释已经写在方法上面了。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //创建 gestureDetector 对象,传入 onGestureListener 的实例 mGestureDetector = new GestureDetector(new GestureListener()); CustomVolumeControlBar controlBar = findViewById(R.id.controlBar); //触摸事件 controlBar.setOnTouchListener(this); //获取焦点 controlBar.setFocusable(true); //启用或者禁用 单击事件 controlBar.setClickable(true); //启用或者禁用 长按事件 controlBar.setLongClickable(true); } /** * 通过调用 GestureDetector 的 onTouchEvent()方法,将捕捉到的 MotionEvent 交给 GestureDetector * 来分析 是否由合适的 callback 函数来处理用户的手势 */ @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); }
上面对一个 自定义View 进行了手势检测。手势检测的接口 和 双击 的接口 都已经实现,可以使用
2,使用内部类
使用内部类的方式,使用这种方式 可以根据情况,用到那个方法就重写那个方法:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //创建 gestureDetector 类的 静态内部类来实现,可以重写任意的方法 mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener(){ final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200; @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { //小例子:判断是左滑 还是右滑 if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY){ Log.e(TAG, "onFling: 左滑"+e1.getX()+"------"+e2.getX() ); }else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY){ Log.e(TAG, "onFling: 右滑 "+e1.getX()+"------"+e2.getX() ); } return false; } @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.e(TAG, "onDoubleTapEvent: 双击" ); return false; } }); CustomVolumeControlBar controlBar = findViewById(R.id.controlBar); //触摸事件 controlBar.setOnTouchListener(this); //获取焦点 controlBar.setFocusable(true); //启用或者禁用 单击事件 controlBar.setClickable(true); //启用或者禁用 长按事件 controlBar.setLongClickable(true); } /** * 通过调用 GestureDetector 的 onTouchEvent()方法,将捕捉到的 MotionEvent 交给 GestureDetector * 来分析 是否由合适的 callback 函数来处理用户的手势 */ @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); }