- Android手势识别01基本手势的处理
- 一简介
- 二按下显示按下单击滚动长按快掷手势
- 1 activity_base_testxml
- 2 BaseTestActivityjava
- 3 图示
- 4 方法分析和说明
- 三双击手势
- 1 使用 GestureDetectorOnDoubleTapListener
- 2 使用 GestureDetectorSimpleOnGestureListener
- 3 图示
- 四GestureDetectorSimpleOnGestureListener
- 五缩放手势
- 1 ScaleGestureActivityjava
- 2 图示
- 六拖拽
- 1 自己处理按下移动的动作重写onTouchEvent事件
- 2 使用手势
- 3 图示
- 七源码
Android手势识别01——基本手势的处理
一、简介
手势对于我们的app有很多的地方都在使用,比如右滑关闭界面等。手势控制分为触发动作(Touch Mechanics,用户手指在屏幕上如何动作)和触发行为(Touch Activities,界面上特定动作在特定情境下引发的结果)。这是因为同样的触发动作(如单次触击)在不同情境下可能会带来不同的结果(如轻触,取消,开启/关闭指示),同样单次触发行为(如放大)可能是由多种触发动作(如捏放,双次触击,双次触击拖拽等)实现。
手势手势 Android 1.6 中加入的。手势还有支持库,尽量使用支持库。
基本手势的使用步骤一般如下:
- 创建手势的监听类(可以继承自GestureDetector.OnGestureListener,或者继承自GestureDetector.SimpleOnGestureListener)
- 创建手势的探测器,如mGestureDetector = new GestureDetectorCompat(this,mOnGestureListener);
- 重写Activity或者View的onTouchEvent的方法,在其中调用探测器的onTouchEvent方法如
@Override public boolean onTouchEvent(MotionEvent event) { mGestureDetector.onTouchEvent(event); return super.onTouchEvent(event); }
二、按下、显示按下、单击、滚动、长按、快掷手势
按下、显示按下、单击、滚动、长按、快掷这些手势我们可以可使用 GestureDetector.OnGestureListener或者GestureDetector.SimpleOnGestureListener来进行监听,请看下面的例子
2.1 activity_base_test.xml
<?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/base_tv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
2.2 BaseTestActivity.java
/**
* <b>Project:</b> gesturedemo<br>
* <b>Create Date:</b> 2017/4/25<br>
* <b>Author:</b> qiwenming<br>
* <b>Description:</b>
* 基本手势测试
* <br>
*/
public class BaseTestActivity extends BaseActivity {
private static final String TAG = "BaseTestActivity";
private GestureDetectorCompat mGestureDetector;
private TextView mBaseTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_test);
mBaseTv = (TextView)findViewById(R.id.base_tv);
mGestureDetector = new GestureDetectorCompat(this,mOnGestureListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
private GestureDetector.OnGestureListener mOnGestureListener = new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent mCurrentDownEvent) {
logger("onDown: ");
Log.i(TAG, "onDown: ");
return true;
}
@Override
public void onShowPress(MotionEvent mCurrentDownEvent) {
logger("onShowPress: ");
Log.i(TAG, "onShowPress: ");
}
@Override
public boolean onSingleTapUp(MotionEvent mCurrentDownEvent) {
logger("onSingleTapUp: ");
Log.i(TAG, "onSingleTapUp: ");
return false;
}
@Override
public boolean onScroll(MotionEvent mCurrentDownEvent, MotionEvent motionEvent1, float velocityX, float velocityY) {
logger("onScroll: "+velocityX+" , "+velocityY);
Log.i(TAG, "onScroll: "+velocityX+" , "+velocityY);
return false;
}
@Override
public void onLongPress(MotionEvent mCurrentDownEvent) {
logger("onLongPress: ");
Log.i(TAG, "onLongPress: ");
}
@Override
public boolean onFling(MotionEvent mCurrentDownEvent, MotionEvent motionEvent1, float velocityX, float velocityY) {
Log.i(TAG, "onFling: "+velocityX+"----"+velocityY);
logger("onFling: "+velocityX+" , "+velocityY);
//右滑关闭acitivity
if(velocityX > 10 && velocityX > Math.abs(velocityY)) {
finish();
}
return true;
}
};
private void logger(String msg){
String log = mBaseTv.getText()+"\n"+msg;
if(log.split(":").length>30){
log = msg;
}
mBaseTv.setText(log);
}
}
2.3 图示
2.4 方法分析和说明
事件 | 说明 |
onDown | 只要按下,这个方法就会执行,也就是说我们的手势中,这个方法一定会执行。 |
onShowPress | 已经按下,但是没有移动或者抬起。此事件通常用于提供视觉反馈给用户,让他们知道他们的行动已经认可即突出元素。 |
onSingleTapUp | 敲击手势的事件 |
onScroll | 滚动。 velocityX说明:左→右 => 负值,右→左 => 正值;velocityY说明:上→下 => 负值,下→上 => 正值 |
onLongPress | 长按 |
onFling | 快掷。 |
三、双击手势
双击手势我们使用的监听是GestureDetector.OnDoubleTapListener或者GestureDetector.SimpleOnGestureListener,想多来说我们使用GestureDetector.SimpleOnGestureListener方便一点。
3.1 使用 GestureDetector.OnDoubleTapListener
BaseTestActivity.java
/**
* <b>Project:</b> gesturedemo<br>
* <b>Create Date:</b> 2017/4/26<br>
* <b>Author:</b> qiwenming<br>
* <b>Description:</b>
* 双击手势
* <br>
*/
public class DoubleTapActivity extends BaseTestActivity {
private TextView mTv;
private GestureDetectorCompat mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_double_tap);
mTv = (TextView)findViewById(R.id.doubletap_tv);
mGestureDetector = new GestureDetectorCompat(this,mOnGestureListener);
mGestureDetector.setOnDoubleTapListener(mOnDoubleTapListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
private GestureDetector.OnDoubleTapListener mOnDoubleTapListener = new GestureDetector.OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
logger("onSingleTapConfirmed:");
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
logger("onDoubleTap:");
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
logger("onDoubleTapEvent:"+MotionEvent.actionToString(e.getAction()));
return false;
}
};
private GestureDetector.OnGestureListener mOnGestureListener = new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@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;
}
};
private void logger(String msg){
String log = mTv.getText()+"\n"+msg;
if(log.split(":").length>30){
log = msg;
}
mTv.setText(log);
}
}
3.2 使用 GestureDetector.SimpleOnGestureListener
我们看到,如果我们使用的是GestureDetector.OnGestureListener,我们需要添加两个监听。而我们使用GestureDetector.SimpleOnGestureListener,就会简单好多。
/**
* <b>Project:</b> gesturedemo<br>
* <b>Create Date:</b> 2017/4/26<br>
* <b>Author:</b> qiwenming<br>
* <b>Description:</b>
* 双击手势
* <br>
*/
public class DoubleTapActivity extends BaseTestActivity {
private TextView mTv;
private GestureDetectorCompat mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_double_tap);
mTv = (TextView)findViewById(R.id.doubletap_tv);
mGestureDetector = new GestureDetectorCompat(this,mDoubleSimpGestureListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
private GestureDetector.SimpleOnGestureListener mDoubleSimpGestureListener = new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
logger("onSingleTapConfirmed:");
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
logger("onDoubleTap:");
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
logger("onDoubleTapEvent:"+MotionEvent.actionToString(e.getAction()));
return false;
}
};
private void logger(String msg){
String log = mTv.getText()+"\n"+msg;
if(log.split(":").length>30){
log = msg;
}
mTv.setText(log);
}
}
3.3 图示
四、GestureDetector.SimpleOnGestureListener
上面我们总是说使用 GestureDetector.SimpleOnGestureListener更为方便一点,我们可以看看这个类
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
OnContextClickListener {
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public void onLongPress(MotionEvent e) {
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
return false;
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
public void onShowPress(MotionEvent e) {
}
public boolean onDown(MotionEvent e) {
return false;
}
public boolean onDoubleTap(MotionEvent e) {
return false;
}
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
public boolean onContextClick(MotionEvent e) {
return false;
}
}
通过上面我们可以看到这个类实现了:GestureDetector.OnGestureListener,GestureDetector.OnDoubleTapListener,GestureDetector.OnContextClickListener,这三个接口,也就是说如果我们是使用到上的上面的手势那么我们可以使用GestureDetector.SimpleOnGestureListener
五、缩放手势
缩放手势,我们使用的是ScaleGestureDetector和ScaleGestureDetector.OnScaleGestureListener
其中ScaleGestureDetector中的getScaleFactor()是用来获取缩放比例的,这个比例是相对于上一次的缩放比例
5.1 ScaleGestureActivity.java
/**
* <b>Project:</b> YuantaiApplication<br>
* <b>Create Date:</b> 2017/4/26<br>
* <b>Author:</b> qiwenming<br>
* <b>Description:</b> <br>
* 缩放手势
*/
public class ScaleGestureActivity extends BaseActivity {
private View mView;
private ScaleGestureDetector mScaleGestureDetector;
private static final String TAG = "ScaleGestureActivity";
private float mScaleFactor = 1.0f;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scale_gesture);
mView = findViewById(R.id.scale_view);
mScaleGestureDetector = new ScaleGestureDetector(this,mScaleGestureListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mScaleGestureDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
private ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener = new ScaleGestureDetector.OnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
mScaleFactor *= scaleGestureDetector.getScaleFactor();
mView.setScaleX(mScaleFactor);
mView.setScaleY(mScaleFactor);
Log.i(TAG, "onScale: "+ scaleGestureDetector.getScaleFactor()+"----"+mScaleFactor);
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector scaleGestureDetector) {
}
};
}
5.2 图示
六、拖拽
拖拽我们使用的其实就是手势中的滚动。
6.1 自己处理按下移动的动作,重写onTouchEvent事件
DragTestActivity.java
/**
* <b>Project:</b> YuantaiApplication<br>
* <b>Create Date:</b> 2017/4/26<br>
* <b>Author:</b> qiwenming<br>
* <b>Description:</b>
* 拖拽
* <br>
*/
public class DragTestActivity extends BaseActivity {
private View mView;
private GestureDetectorCompat mGestureDetectorCompat;
private static final String TAG = "DragTestActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drag_test);
mView = findViewById(R.id.drag_view);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
onMyDrag(event);
return super.onTouchEvent(event);
}
private float mLastX = 0;
private float mLastY = 0;
private float mOffsetX = 0;
private float mOffsetY = 0;
public void onMyDrag(MotionEvent event){
switch (event.getActionMasked()){
case MotionEvent.ACTION_DOWN:
mLastX = event.getX();
mLastY = event.getY();
Log.i(TAG, "onMyDrag:ACTION_DOWN "+event.getX()+" , "+event.getY());
break;
case MotionEvent.ACTION_MOVE:
mOffsetX += event.getX()-mLastX;
mOffsetY += event.getY()-mLastY;
mLastX = event.getX();
mLastY = event.getY();
mView.setTranslationX( mOffsetX );
mView.setTranslationY( mOffsetY );
break;
}
}
}
6.2 使用手势
DragTestActivity.java
/**
* <b>Project:</b> YuantaiApplication<br>
* <b>Create Date:</b> 2017/4/26<br>
* <b>Author:</b> qiwenming<br>
* <b>Description:</b>
* 拖拽
* <br>
*/
public class DragTestActivity extends BaseActivity {
private View mView;
private GestureDetectorCompat mGestureDetectorCompat;
private static final String TAG = "DragTestActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drag_test);
mView = findViewById(R.id.drag_view);
mGestureDetectorCompat = new GestureDetectorCompat(this,mSimpleOnGestureListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetectorCompat.onTouchEvent(event);
return super.onTouchEvent(event);
}
private float mOffsetScX = 0;
private float mOffsetScY = 0;
private GestureDetector.SimpleOnGestureListener mSimpleOnGestureListener = new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
mOffsetScX += -distanceX;
mOffsetScY += -distanceY;
mView.setTranslationX( mOffsetScX );
mView.setTranslationY( mOffsetScY );
return true;
}
};
}
6.3 图示
七、源码
源码下载: https://github.com/qiwenming/GestureDemo/tree/master/app/src/main/java/com/qwm/gesturedemo/basetest