Android触控屏幕Gesture(GestureDetector和SimpleOnGestureListener的使用教程) 分类:An...
1、当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等,我们知道View类有个View.OnTouchListener内部接口,通过重写他的onTouch(Viewv,MotionEventevent)方法,我们可以处理一些touch事件,但是这个方法太过简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦(因为我们要自己根据用户触摸的轨迹去判断是什么手势)Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势,主要是通过他的onTouchEvent(event)方法完成了不同手势的识别。虽然他能识别手势,但是不同的手势要怎么处理,应该是提供给程序员实现的,因此这个类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener,SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,这个类实现了上述两个接口(但是所有的方法体都是空的),该类是static class,也就是说它实际上是一个外部类。程序员可以在外部继承这个类,重写里面的手势处理方法。 通过GestureDetector的构造方法可以将SimpleOnGestureListener对象传递进去,这样GestureDetector能处理不同的手势了。 2.、具体用法: [java] view plain copy /** *当我们捕捉到Touch操作的时候,如何识别出用户的Gesture?这里我们需要GestureDetector.OnGestureListener接口的帮助 * *@authorHB */ publicclassMySurfaceViewextendsSurfaceViewimplementsOnGestureListener, OnTouchListener,Callback{ GestureDetectorgd; Contextcontext; publicMySurfaceView(Contextcontext){ super(context); this.context=context; setFocusable(true); requestFocus(); this.setLongClickable(true); this.setOnTouchListener(this); setFocusable(true); gd=newGestureDetector(newMySimpleGesture());//这里或者可以直接传递this参数,因为本类已经继承了OnGestureListener接口,也可以把new //MySimpleGesture(),它继承了SimpleOnGestureListener类;,两种方法都可以,只是把两种方法归在一个里面,方便学习; //。实惠屏幕触控事件; gd.setIsLongpressEnabled(true); //TODOAuto-generatedconstructorstub } //用户轻触触摸屏,由1个MotionEventACTION_DOWN触发 @Override publicbooleanonDown(MotionEvente){ //TODOAuto-generatedmethodstub System.out.println("onDown"); returnfalse; } /* *用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEventACTION_DOWN触发 *注意和onDown()的区别,强调的是没有松开或者拖动的状态(单击没有松开或者移动时候就触发此事件,再触发onLongPress事件) */ @Override publicvoidonShowPress(MotionEvente){ //TODOAuto-generatedmethodstub System.out.println("onShowPress"); } //用户(轻触触摸屏后)松开,由一个1个MotionEventACTION_UP触发 @Override publicbooleanonSingleTapUp(MotionEvente){ //TODOAuto-generatedmethodstub System.out.println("onSingleTopUp"); returnfalse; } //用户按下触摸屏,并拖动,由1个MotionEventACTION_DOWN,多个ACTION_MOVE触发 @Override publicbooleanonScroll(MotionEvente1,MotionEvente2,floatdistanceX, floatdistanceY){ System.out.println("onScroll"); //TODOAuto-generatedmethodstub returnfalse; } //用户长按触摸屏,由多个MotionEventACTION_DOWN触发 @Override publicvoidonLongPress(MotionEvente){ //TODOAuto-generatedmethodstub System.out.println("onLongPress"); } /* *用户按下触摸屏、快速移动后松开,由1个MotionEventACTION_DOWN,多个ACTION_MOVE, *1个ACTION_UP触发(non-Javadoc) *Fling事件的处理代码:除了第一个触发Fling的ACTION_DOWN和最后一个ACTION_MOVE中包含的坐标等信息外 *,我们还可以根据用户在X轴或者Y轴上的移动速度作为条件 *比如下面的代码中我们就在用户移动超过100个像素,且X轴上每秒的移动速度大于200像素时才进行处理。 * *@seeandroid.view.GestureDetector.OnGestureListener#onFling(android.view. *MotionEvent,android.view.MotionEvent,float,float) *这个例子中,tv.setLongClickable(true)是必须的,因为 *只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN) *,我们同样可以通过layout定义中的android:longClickable来做到这一点 */ @Override publicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX, floatvelocityY){ //TODOAuto-generatedmethodstub System.out.println("onFling"); //参数解释: //e1:第1个ACTION_DOWNMotionEvent //e2:最后一个ACTION_MOVEMotionEvent //velocityX:X轴上的移动速度,像素/秒 //velocityY:Y轴上的移动速度,像素/秒 //触发条件: //X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒 finalintFLING_MIN_DISTANCE=100,FLING_MIN_VELOCITY=200; if(e1.getX()-e2.getX()>FLING_MIN_DISTANCE &&Math.abs(velocityX)>FLING_MIN_VELOCITY){ //Flingleft Log.i("MyGesture","Flingleft"); Toast.makeText(context,"FlingLeft",Toast.LENGTH_SHORT).show(); }elseif(e2.getX()-e1.getX()>FLING_MIN_DISTANCE &&Math.abs(velocityX)>FLING_MIN_VELOCITY){ //Flingright Log.i("MyGesture","Flingright"); Toast.makeText(context,"FlingRight",Toast.LENGTH_SHORT).show(); } returntrue; } /** *当发行屏幕触控事件的时候,首先出发此方法,再通过此方法,监听具体的整件 *在onTouch()方法中,我们调用GestureDetector的onTouchEvent *()方法,将捕捉到的MotionEvent交给GestureDetector来分析是否有合适的callback函数来处理用户的手势 */ @Override publicbooleanonTouch(Viewv,MotionEventevent){ //TODOAuto-generatedmethodstub System.out.println("onTouch"); returngd.onTouchEvent(event); } @Override publicvoidsurfaceCreated(SurfaceHolderholder){ //TODOAuto-generatedmethodstub } @Override publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth, intheight){ //TODOAuto-generatedmethodstub } @Override publicvoidsurfaceDestroyed(SurfaceHolderholder){ //TODOAuto-generatedmethodstub } /** *SimpleOnGestureListenerimplementsGestureDetector.OnDoubleTapListener, *GestureDetector.OnGestureListener */ privateclassMySimpleGestureextendsSimpleOnGestureListener{ //双击的第二下Touchdown时触发 publicbooleanonDoubleTap(MotionEvente){ Log.i("MyGesture","onDoubleTap"); returnsuper.onDoubleTap(e); } //双击的第二下Touchdown和up都会触发,可用e.getAction()区分 publicbooleanonDoubleTapEvent(MotionEvente){ Log.i("MyGesture","onDoubleTapEvent"); returnsuper.onDoubleTapEvent(e); } //Touchdown时触发 publicbooleanonDown(MotionEvente){ Log.i("MyGesture","onDown"); returnsuper.onDown(e); } //Touch了滑动一点距离后,up时触发 publicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX, floatvelocityY){ Log.i("MyGesture","onFling"); returnsuper.onFling(e1,e2,velocityX,velocityY); } //Touch了不移动一直Touchdown时触发 publicvoidonLongPress(MotionEvente){ Log.i("MyGesture","onLongPress"); super.onLongPress(e); } //Touch了滑动时触发 publicbooleanonScroll(MotionEvente1,MotionEvente2, floatdistanceX,floatdistanceY){ Log.i("MyGesture","onScroll"); returnsuper.onScroll(e1,e2,distanceX,distanceY); } /* *Touch了还没有滑动时触发(1)onDown只要TouchDown一定立刻触发(2)Touch *Down后过一会没有滑动先触发onShowPress再触发onLongPressSo:TouchDown后一直不滑动,onDown *->onShowPress->onLongPress这个顺序触发。 */ publicvoidonShowPress(MotionEvente){ Log.i("MyGesture","onShowPress"); super.onShowPress(e); } /* *两个函数都是在TouchDown后又没有滑动(onScroll),又没有长按(onLongPress),然后TouchUp时触发 *点击一下非常快的(不滑动)TouchUp:onDown->onSingleTapUp->onSingleTapConfirmed *点击一下稍微慢点的(不滑动)TouchUp://确认是单击事件触发 *onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed */ publicbooleanonSingleTapConfirmed(MotionEvente){ Log.i("MyGesture","onSingleTapConfirmed"); returnsuper.onSingleTapConfirmed(e); } publicbooleanonSingleTapUp(MotionEvente){ Log.i("MyGesture","onSingleTapUp"); returnsuper.onSingleTapUp(e); } } } 结果: 1、当单击屏幕的时候,输出: 2、当单击等一会再松开时候输出( 3、当用户按住不放的时候,输出: 4、当用户按住不放,拖动鼠标的时候输出: 5、当用户按住不放,快速拖动鼠标的时候: 6、当用户双击的时候(观察与单击的区别---onDubleTab在第二次按下Down的时候才出发,说明 是双击事件在onDown事件之前;): 本文转自莫水千流博客园博客,原文链接:http://www.cnblogs.com/zhoug2020/p/6593094.html,如需转载请自行联系原作者