您的位置:首页 > 移动开发 > Android开发

Android 触摸手势(来自官方文档)

2016-09-02 11:38 281 查看

Detecting Common Gestures(参考来自官方文档)

本文翻译自安卓官方文档: https://developer.android.com/training/gestures/detector.html#detect

Detecting Common Gestures,一般分为两个阶段:

一: Gathering data about touch events.(收集数据)

二: Interpreting the data to see if it meets the criteria for any of the gestures your app supports.(根据自己需要使用检测到的数据)

本文主要涉及到 GestureDetectorCompat 和 MotionEventCompat 两个类,这两个类在 Support Library中,Support Library classes 可以支持在API 1.6版本 以上使用.

另外,关于 MotionEvent 和MotionEventCompat: 和MotionEventCompat不是MotionEvent的替代,它仅仅提供了一些静态方法,

Note that MotionEventCompat is not a replacement for the MotionEvent class. Rather, it provides static utility methods to which you pass your MotionEvent object in order to receive the desired action associated with that event

Gather Data

当手指触摸屏幕时,就会触发 onTouchEvent() 方法,作为一个 系统任务 接收触摸事件,

当最后一个手指离开时,结束 gesture ,并把 MotionEvent 传递给onTouchEvent(),这样就可以

根据需要使用MotionEvent提供的详细测量数据.

在Activity 或者View中获取触摸事件

为了截获touch事件,你需要覆写Activity或View的onTouchEvent方法

下面是一个在Activity中,获取触摸事件的示例:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event) {
final String DEBUG_TAG = "Gestures";

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);
}

}
}


如图:



接下来看看在View中如何获取触摸事件呢:

在view中,你可以使用 setOnTouchListener() 方法依附于任何一个 实现了 View.OnTouchListener 接口的对象.这样就可以不继承View而处理点击事件

public class MainActivity extends AppCompatActivity implements View.OnTouchListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TextView textView = (TextView) findViewById(R.id.tv);
textView.setOnTouchListener(this);

}

@Override
public boolean onTouch(View v, MotionEvent event) {

// ... Respond to touch events
final String DEBUG_TAG = "Gestures";

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);
}
}
}


运行后如图:



可以看出,当点击TextView时,会相应不同的触摸事件.而点击TextView以外的部分则不会.

注意:创建Listener的时候,对于ACTION_DOWN 如果返回的是 false,listener将不会调用 ACTION_MOVE 和ACTION_UP 等事件,这是因为ACTION_DOWN 是所有触摸事件的开始

当然,如果你创建一个自定义的View,你可以重写 上面的 onTouchEvent() 方法.

Detect Gestures(检测手势)

Android提供了GestureDetector 类来检测一般的手势。

Detecting All Supported Gestures

 1.生成GestureDetector 对象(或GestureDetectorCompat对象),构造时的参数传入监听器对象。

  监听器对象实现GestureDetector.OnGestureListener 接口。当一个触摸事件发生的时候,接口 GestureDetector.OnGestureListener 就会通知用户.

为了让 GestureDetector对象接收到事件,需要覆写View或Activity中的 onTouchEvent()方法,将事件传递给detector对象。

public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
private static final String DEBUG_TAG = "Gestures";
private GestureDetector mDetector;

@Override
protected 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 GestureDetector(this, this);
// Set the gesture detector as the double tap
// listener.
mDetector.setOnDoubleTapListener(this);

}

//为了让 GestureDetector对象接收到事件,需要覆写View或Activity中的 onTouchEvent()方法,将事件传递给detector对象
@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 void onShowPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onShowPress:-------------- " + 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 onLongPress(MotionEvent event) {
Log.d(DEBUG_TAG, "onLongPress:-------------- " + event.toString());
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.d(DEBUG_TAG, "onFling: --------------" + e1.toString()+e2.toString());
return true;
}

@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
Log.d(DEBUG_TAG, "onSingleTapConfirmed:-------------- " + event.toString());
return true;
}
@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;
}
}


实现 GestureDetector.OnGestureListener 接口需要重写一下抽象方法



* 实现 GestureDetector.OnDoubleTapListener 接口需要重写以下方法:



上述方法,返回值为 ture 表明拦截该事件,反而言之,返回false表明不拦截,事件继续传递.

通过上面的实例,在实际操作之后,你就会明白 你的一次屏幕触摸竟会怎样引起一个相互作用的MotionEvent事件,你的一次简单的触摸会引起怎样的复杂的 事件交互.

GestureDetector.SimpleOnGestureListener类

如果你仅仅是想利用其中的一些手势而不是全部,那么你可以选择继承GestureDetector.SimpleOnGestureListener类,这是一个适配器模式,即这个类实现了GestureDetector.OnGestureListener 接口,为其中所有的方法提供了空实现(返回值都是false),当继承GestureDetector.SimpleOnGestureListener类时,子类只需要覆写感兴趣的方法,其他方法是空实现。

下面这个实例,创建了一个内部类继承了 GestureDetector.SimpleOnGestureListener ,并且选择性的重写了 GestureDetector.SimpleOnGestureListener 的 onDown() 和 onFling() 方法

public class MainActivity extends AppCompatActivity{
private static final String DEBUG_TAG = "Gestures";
private GestureDetectorCompat mGesture;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mGesture = new GestureDetectorCompat(this,new MyGestureListener());

}

@Override
public boolean onTouchEvent(MotionEvent event) {
this.mGesture.onTouchEvent(event);
return super.onTouchEvent(event);
}

class MyGestureListener extends GestureDetector.SimpleOnGestureListener{

//选择性的重写 GestureDetector.SimpleOnGestureListener 的方法
@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;
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android GestureDet 手势