我希望我的应用程序能够识别用户在手机屏幕上从右向左滑动。
如何做到这一点?
我希望我的应用程序能够识别用户在手机屏幕上从右向左滑动。
如何做到这一点?
当前回答
这段代码检测左右滑动,避免了废弃的API调用,并对之前的答案进行了其他改进。
/**
* Detects left and right swipes across a view.
*/
public class OnSwipeTouchListener implements OnTouchListener {
private final GestureDetector gestureDetector;
public OnSwipeTouchListener(Context context) {
gestureDetector = new GestureDetector(context, new GestureListener());
}
public void onSwipeLeft() {
}
public void onSwipeRight() {
}
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_DISTANCE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float distanceX = e2.getX() - e1.getX();
float distanceY = e2.getY() - e1.getY();
if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (distanceX > 0)
onSwipeRight();
else
onSwipeLeft();
return true;
}
return false;
}
}
}
像这样使用它:
view.setOnTouchListener(new OnSwipeTouchListener(context) {
@Override
public void onSwipeLeft() {
// Whatever
}
});
其他回答
@Mirek Rusin的回答很好。 但是,有一个小bug,需要修复
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
if (getOnSwipeListener() != null) {
getOnSwipeListener().onSwipeRight();
}
} else {
if (getOnSwipeListener() != null) {
getOnSwipeListener().onSwipeLeft();
}
}
result = true;
}
}
else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
if (getOnSwipeListener() != null) {
getOnSwipeListener().onSwipeBottom();
}
} else {
if (getOnSwipeListener() != null) {
getOnSwipeListener().onSwipeTop();
}
}
result = true;
}
有什么不同?我们设置result = true,仅当我们检查了所有的需求(SWIPE_THRESHOLD和SWIPE_VELOCITY_THRESHOLD都是Ok的)。这是重要的,如果我们放弃滑动,如果一些需求没有实现,我们必须做smth在OnSwipeTouchListener的onTouchEvent方法!
这段代码检测左右滑动,避免了废弃的API调用,并对之前的答案进行了其他改进。
/**
* Detects left and right swipes across a view.
*/
public class OnSwipeTouchListener implements OnTouchListener {
private final GestureDetector gestureDetector;
public OnSwipeTouchListener(Context context) {
gestureDetector = new GestureDetector(context, new GestureListener());
}
public void onSwipeLeft() {
}
public void onSwipeRight() {
}
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_DISTANCE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
float distanceX = e2.getX() - e1.getX();
float distanceY = e2.getY() - e1.getY();
if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (distanceX > 0)
onSwipeRight();
else
onSwipeLeft();
return true;
}
return false;
}
}
}
像这样使用它:
view.setOnTouchListener(new OnSwipeTouchListener(context) {
@Override
public void onSwipeLeft() {
// Whatever
}
});
使用SwipeListView,让它为你处理手势检测。
import android.content.Context
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
/**
* Detects left and right swipes across a view.
*/
class OnSwipeTouchListener(context: Context, onSwipeCallBack: OnSwipeCallBack?) : OnTouchListener {
private var gestureDetector : GestureDetector
private var onSwipeCallBack: OnSwipeCallBack?=null
init {
gestureDetector = GestureDetector(context, GestureListener())
this.onSwipeCallBack = onSwipeCallBack!!
}
companion object {
private val SWIPE_DISTANCE_THRESHOLD = 100
private val SWIPE_VELOCITY_THRESHOLD = 100
}
/* fun onSwipeLeft() {}
fun onSwipeRight() {}*/
override fun onTouch(v: View, event: MotionEvent): Boolean {
return gestureDetector.onTouchEvent(event)
}
private inner class GestureListener : SimpleOnGestureListener() {
override fun onDown(e: MotionEvent): Boolean {
return true
}
override fun onFling(eve1: MotionEvent?, eve2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
try {
if(eve1 != null&& eve2!= null) {
val distanceX = eve2?.x - eve1?.x
val distanceY = eve2?.y - eve1?.y
if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (distanceX > 0)
onSwipeCallBack!!.onSwipeLeftCallback()
else
onSwipeCallBack!!.onSwipeRightCallback()
return true
}
}
}catch (exception:Exception){
exception.printStackTrace()
}
return false
}
}
}
扩展Mirek的回答,当你想在滚动视图中使用滑动手势时。默认情况下,滚动视图的触摸监听器被禁用,因此滚动动作不会发生。为了解决这个问题,您需要重写Activity的dispatchTouchEvent方法,并在您完成自己的侦听器后返回该方法的继承版本。
为了对Mirek的代码做一些修改: 我在OnSwipeTouchListener中添加了一个gestureDetector getter。
public GestureDetector getGestureDetector(){
return gestureDetector;
}
在Activity中声明OnSwipeTouchListener作为类范围的字段。
OnSwipeTouchListener onSwipeTouchListener;
相应修改用法代码:
onSwipeTouchListener = new OnSwipeTouchListener(MyActivity.this) {
public void onSwipeTop() {
Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
}
public void onSwipeRight() {
Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
}
public void onSwipeLeft() {
Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
}
public void onSwipeBottom() {
Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
}
});
imageView.setOnTouchListener(onSwipeTouchListener);
并覆盖活动内部的dispatchTouchEvent方法:
@Override
public boolean dispatchTouchEvent(MotionEvent ev){
swipeListener.getGestureDetector().onTouchEvent(ev);
return super.dispatchTouchEvent(ev);
}
现在滚动和滑动动作都可以工作了。