检测常见的手势 当用户将一个或多个手指放置于屏幕上时,就会触发一个“触摸手势”,你的应用程序将触摸动作解释为一个特定的手势。手势检测分为两个阶段: 1.收集触摸事件的数据。 2.识别收集的数据,看它是否满足你的应用程序所支持手势的标准。 支持库中的类 这节中所用的例子使用了GestureDetectorCompat和MotionEventCompat类。这些类都在Support Library中。 收集数据 当用户将一个或多个手指放置于屏幕上时,就会触发接受到触摸事件的View的onTouchEvent()回调函数。对于每一个串触摸事件序列,最终被确定为一个手势,onTouchEvent()被触发多次。 手势以用户第一次触摸屏幕开始,系统将不断跟踪用户手指所在位置,最终通过用户手指离开屏幕作为结束。在整个交互中,MotionEvent被传入onTouchEvent()方法,提供了每一次交互的详细信息。你的应用使用由MotionEvent提供的数据来确定一个应用关注的手势是否发生。 捕获Activity或View的触摸事件 为了在Activity或View中捕获触摸事件,覆盖onTouchEvent()回调方法。
代码片段,双击复制
public class MainActivity extends Activity {
...
// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event){
int action = MotionEventCompat.getActionMasked(event);
switch (action) {
case (MotionEvent.ACTION_DOWN) :
Log.d(DEBUG_TAG, "Action was DOWN" );
return true ;
case (MotionEvent.ACTION_MOVE) :
Log.d(DEBUG_TAG, "Action was MOVE" );
return true ;
case (MotionEvent.ACTION_UP) :
Log.d(DEBUG_TAG, "Action was UP" );
return true ;
case (MotionEvent.ACTION_CANCEL) :
Log.d(DEBUG_TAG, "Action was CANCEL" );
return true ;
case (MotionEvent.ACTION_OUTSIDE) :
Log.d(DEBUG_TAG, "Movement occurred outside bounds " +
"of current screen element" );
return true ;
default :
return super .onTouchEvent(event);
}
}
然后你可以自己处理这些事件来确定是否有手势动作发生。但是,如果你的应用使用一些常见的手势,例如双击,长按,滑动,等等,你可以使用GestureDetector类。GestureDetector能够使你更方便的检测常见手势,不用自己处理触摸事件。
捕获view的触摸事件
代码片段,双击复制
View myView = findViewById(R.id.my_view);
myView.setOnTouchListener( new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// ... Respond to touch events
return true ;
}
});
需要注意的是,如果对于ACTION_DOWN事件返回false,则这次事件序列中的ACTION_MOVE ACTION_UP事件将不会被处理。这是因为ACTION_DOWN是所有触摸事件的起点。
检测手势
检测所有支持的手势
当你初始化一个GestureDetectorCompat对象时,它需要的参数之一是一个类,实现了GestureDetector.OnGestureListener接口。当一个特定的触摸事件发生时,GestureDetector.OnGestureListener就会通知用户。为了使GestureDetector对象接收事件,你需要覆盖View或Activity的onTouchEvent函数,并将所有的events传递到detector实例。
代码片段,双击复制
public class MainActivity extends Activity implements
GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener{
private static final String DEBUG_TAG = "Gestures" ;
private GestureDetectorCompat mDetector;
// Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
mDetector = new GestureDetectorCompat( this , this );
// Set the gesture detector as the double tap
// listener.
mDetector.setOnDoubleTapListener( this );
}
@Override
public boolean onTouchEvent(MotionEvent event){
this .mDetector.onTouchEvent(event);
// Be sure to call the superclass implementation
return super .onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG, "onDown: " + event.toString());
return true ;
}
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
return true ;
}
@Override
public void onLongPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());
return true ;
}
@Override
public void onShowPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
return true ;
}
@Override
public boolean onDoubleTap(MotionEvent event) {
Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
return true ;
}
@Override
public boolean onDoubleTapEvent(MotionEvent event) {
Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
return true ;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
return true ;
}
}
检测所有手势的一个子集
如果你只想处理一部分手势,你可以继承GestureDetector.SimpleOnGestureListener。
GestureDetector.SimpleOnGestureListener提供了一个触摸事件的所有实现,所有函数的返回值都为false。因此你可以只覆盖那些你关心的方法。
不论是否使用GestureDetector.OnGestureListener,最好的做法就是实现onDown()函数并返回true。这是因为所有的手势都以onDown()消息开始。如果在onDown中返回false,则系统认为你想忽略剩余的手势动作,GestureDetector.OnGestureListener 将不会被调用。这将会给你的应用程序带来不可预期的问题。只有你想要忽略整个手势动作时,在onDown中返回false。
代码片段,双击复制
public class MainActivity extends Activity {
private GestureDetectorCompat mDetector;
@Override
public void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDetector = new GestureDetectorCompat( this , new MyGestureListener());
}
@Override
public boolean onTouchEvent(MotionEvent event){
this .mDetector.onTouchEvent(event);
return super .onTouchEvent(event);
}
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
private static final String DEBUG_TAG = "Gestures" ;
@Override
public boolean onDown(MotionEvent event) {
Log.d(DEBUG_TAG, "onDown: " + event.toString());
return true ;
}
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
return true ;
}
}
}
















