手势识别器GestureDetector
手势检测用于辅助检测用户的单击、滑动、长按、双击等行为。当然我们完全可以在View的onTouchEvent方法中实现所有的监听,但有的时候用手势识别器更方便,比如说:监听用户双击行为。
它的使用步骤很简单,就两步:
1.创建GestureDetector对象并实现OnGestureDetectorListener或者OnDoubleTapListener(监听双击行为)接口
2.为了让我们的GestureDetector对象能到接收到触摸事件,我们需要重写 View 或 Activity 的 onTouchEvent() 函数,并且把所有捕获到的事件传递给 detector 实例。
简单的app展示:(第一个界面双击后跳转第二个界面,第二个界面左右滑动跳转到前一个和后一个界面)
public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener { private static final String DEBUG_TAG = "TAG"; private GestureDetectorCompat mDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //传入上下文和注册单击监听 mDetector = new GestureDetectorCompat(this, this); //设置双击监听 mDetector.setOnDoubleTapListener(this); } /** * 为了让我们的GestureDetector对象能到接收到触摸事件, * 我们需要重写 View 或 Activity 的 onTouchEvent() 函数, * 并且把所有捕获到的事件传递给 detector 实例 */ @Override public boolean onTouchEvent(MotionEvent event) { //为了让我们的GestureDetector对象能到接收到触摸事件 this.mDetector.onTouchEvent(event); //此处调用父类的onTouchEvent(event)方法 return super.onTouchEvent(event); } /** * 严格的单击行为(不可能是双击中的一次单击) */ @Override public boolean onSingleTapConfirmed(MotionEvent e) { Log.d(DEBUG_TAG, "严格的单击: " + e.toString()); return false; } /** * 双击(由两次单击组成,不可能和onSingleTapConfirmed共存) */ @Override public boolean onDoubleTap(MotionEvent e) { Log.d(DEBUG_TAG, "双击: " + e.toString()); return false; } /** * 表示发生了双击行为,在双击期间ACITON_DOWN,ACTION_MOVE,ACTION_UP,都会触发此回调 */ @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.d(DEBUG_TAG, "双击行为: " + e.toString()); startActivity(new Intent(this, SecondActivity.class)); return false; } /** * 表示轻轻触摸屏幕的一瞬间,由单个ACTION_DOWN组成 */ @Override public boolean onDown(MotionEvent e) { Log.d(DEBUG_TAG, "触摸屏幕的一瞬间: " + e.toString()); return false; } /** * 双指轻轻触摸屏,尚未松开或拖动 */ @Override public void onShowPress(MotionEvent e) { Log.d(DEBUG_TAG, "双指轻轻触摸屏: " + e.toString()); } /** * 手指松开后,伴随着一个ACTION_UP事件,是一次单击行为 */ @Override public boolean onSingleTapUp(MotionEvent e) { Log.d(DEBUG_TAG, "手指松开后: " + e.toString()); return false; } /** * 手指按下屏幕并拖动,由一个ACITON_DOWN,和多个ACTION_MOVE触发 */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.d(DEBUG_TAG, "手指按下屏幕并拖动: " + e1.toString() + e2.toString()); return false; } /** * 用户长久的按着屏幕不放,即长按 */ @Override public void onLongPress(MotionEvent e) { Log.d(DEBUG_TAG, "长按: " + e.toString()); } /** * 快速滑动行为,由一个ACTION_DOWN,多个ACTION_MOVE,和一个ACTION_UP触发 */ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.d(DEBUG_TAG, "快速滑动行为: " + e1.toString() + e2.toString()); return false; } }
public class SecondActivity extends AppCompatActivity { private GestureDetectorCompat mDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); mDetector = new GestureDetectorCompat(this, new MyGestureListener()); } @Override public boolean onTouchEvent(MotionEvent event) { this.mDetector.onTouchEvent(event); return super.onTouchEvent(event); } /** * 如果我们只想处理几种手势, * 那么可以选择继承 GestureDetector.SimpleOnGestureListener 类, * 而不是实现 GestureDetector.OnGestureListener 接口。 */ class MyGestureListener extends GestureDetector.SimpleOnGestureListener { /** * @param e1 * :起点的MotionEvent * @param e2 * :终点的MotionEvent * @param velocityX * :水平方向的移动速度 * @param velocityY * :垂直方向的移动速度 * @return */ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { //过滤竖直方向的滑动 if (Math.abs(e2.getRawY() - e1.getRawY()) > 100) { return true; } else if (e2.getRawX() - e1.getRawX() > 100) { //向右滑动 startActivity(new Intent(SecondActivity.this, MainActivity.class)); } else if (e2.getRawX() - e1.getRawX() < 100) { startActivity(new Intent(SecondActivity.this, ThirdActivity.class)); } else if (Math.abs(velocityX) < 200) {//滑动速度很慢的时候也不跳界面 return true; } return super.onFling(e1, e2, velocityX, velocityY); } } }