zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

理解Android的手势识别提高APP的用户体验

AndroidApp识别 用户 体验 理解 提高 手势
2023-06-13 09:15:01 时间
对于触摸屏,其原生的消息无非按下、抬起、移动这几种,我们只需要简单重载onTouch或者设置触摸侦听器setOnTouchListener即可进行处理。不过,为了提高我们的APP的用户体验,有时候我们需要识别用户的手势,Android给我们提供的手势识别工具GestureDetector就可以帮上大忙了。

基础
GestureDetector的工作原理是,当我们接收到用户触摸消息时,将这个消息交给GestureDetector去加工,我们通过设置侦听器获得GestureDetector处理后的手势。

GestureDetector提供了两个侦听器接口,OnGestureListener处理单击类消息,OnDoubleTapListener处理双击类消息。

OnGestureListener的接口有这几个:
//单击,触摸屏按下时立刻触发
abstractbooleanonDown(MotionEvente);
//抬起,手指离开触摸屏时触发(长按、滚动、滑动时,不会触发这个手势)
abstractbooleanonSingleTapUp(MotionEvente);
//短按,触摸屏按下后片刻后抬起,会触发这个手势,如果迅速抬起则不会
abstractvoidonShowPress(MotionEvente);
//长按,触摸屏按下后既不抬起也不移动,过一段时间后触发
abstractvoidonLongPress(MotionEvente);
//滚动,触摸屏按下后移动
abstractbooleanonScroll(MotionEvente1,MotionEvente2,floatdistanceX,floatdistanceY);
//滑动,触摸屏按下后快速移动并抬起,会先触发滚动手势,跟着触发一个滑动手势
abstractbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX,floatvelocityY);
OnDoubleTapListener的接口有这几个:
//双击,手指在触摸屏上迅速点击第二下时触发
abstractbooleanonDoubleTap(MotionEvente);
//双击的按下跟抬起各触发一次
abstractbooleanonDoubleTapEvent(MotionEvente);
//单击确认,即很快的按下并抬起,但并不连续点击第二下
abstractbooleanonSingleTapConfirmed(MotionEvente);
有时候我们并不需要处理上面所有手势,方便起见,Android提供了另外一个类SimpleOnGestureListener实现了如上接口,我们只需要继承SimpleOnGestureListener然后重载感兴趣的手势即可。

应用
STEP1:创建手势侦听对象
复制代码代码如下:

packagenoodies.blog.csdn.net;
importandroid.content.Context;
importandroid.view.MotionEvent;
importandroid.view.GestureDetector.SimpleOnGestureListener;
importandroid.widget.Toast;
publicclassMyGestureListenerextendsSimpleOnGestureListener{
privateContextmContext;
MyGestureListener(Contextcontext){
mContext=context;
}
@Override
publicbooleanonDown(MotionEvente){
Toast.makeText(mContext,"DOWN"+e.getAction(),Toast.LENGTH_SHORT).show();
returnfalse;
}
@Override
publicvoidonShowPress(MotionEvente){
Toast.makeText(mContext,"SHOW"+e.getAction(),Toast.LENGTH_SHORT).show();
}
@Override
publicbooleanonSingleTapUp(MotionEvente){
Toast.makeText(mContext,"SINGLEUP"+e.getAction(),Toast.LENGTH_SHORT).show();
returnfalse;
}
@Override
publicbooleanonScroll(MotionEvente1,MotionEvente2,
floatdistanceX,floatdistanceY){
Toast.makeText(mContext,"SCROLL"+e2.getAction(),Toast.LENGTH_SHORT).show();
returnfalse;
}
@Override
publicvoidonLongPress(MotionEvente){
Toast.makeText(mContext,"LONG"+e.getAction(),Toast.LENGTH_SHORT).show();
}
@Override
publicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX,
floatvelocityY){
Toast.makeText(mContext,"FLING"+e2.getAction(),Toast.LENGTH_SHORT).show();
returnfalse;
}
@Override
publicbooleanonDoubleTap(MotionEvente){
Toast.makeText(mContext,"DOUBLE"+e.getAction(),Toast.LENGTH_SHORT).show();
returnfalse;
}
@Override
publicbooleanonDoubleTapEvent(MotionEvente){
Toast.makeText(mContext,"DOUBLEEVENT"+e.getAction(),Toast.LENGTH_SHORT).show();
returnfalse;
}
@Override
publicbooleanonSingleTapConfirmed(MotionEvente){
Toast.makeText(mContext,"SINGLECONF"+e.getAction(),Toast.LENGTH_SHORT).show();
returnfalse;
}
}

STEP2:设置手势识别
我们可以在Activity里设置手势识别:
复制代码代码如下:

packagenoodies.blog.csdn.net;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.view.GestureDetector;
importandroid.view.MotionEvent;
publicclassGestureTestActivityextendsActivity{
privateGestureDetectormGestureDetector;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mGestureDetector=newGestureDetector(this,newMyGestureListener(this));
}
@Override
publicbooleanonTouchEvent(MotionEventevent){
returnmGestureDetector.onTouchEvent(event);
}
}

也可以在自定义的View里面设置手势识别:
复制代码代码如下: 
packagenoodies.blog.csdn.net;
importandroid.content.Context;
importandroid.util.AttributeSet;
importandroid.view.GestureDetector;
importandroid.view.MotionEvent;
importandroid.view.View;
publicclassMyViewextendsView{
privateGestureDetectormGestureDetector;
publicMyView(Contextcontext,AttributeSetattrs){
super(context,attrs);
mGestureDetector=newGestureDetector(context,newMyGestureListener(context));
setLongClickable(true);
this.setOnTouchListener(newOnTouchListener(){
publicbooleanonTouch(Viewv,MotionEventevent){
returnmGestureDetector.onTouchEvent(event);
}
});
}
}

陷阱
对于自定义View,使用手势识别有两处陷阱可能会浪费你的不少时间。
1:View必须设置longClickable为true,否则手势识别无法正确工作,只会返回Down,Show,Long三种手势
2:必须在View的onTouchListener中调用手势识别,而不能像Activity一样重载onTouchEvent,否则同样手势识别无法正确工作

测试结果
下面是各种操作返回的手势序列,数值0表示触摸屏按下,1表示抬起
单击:down0,singleup1,singleconf0
短按:down0,show0,singleup1
长按:down0,show0,long0
双击:down0,singleup1,double0,doubleevent0,down0,doubleevent1
滚动:down0,(show0),scrool2...
滑动:down0,(show0),scrool2...,fling1