我希望我的应用程序能够识别用户在手机屏幕上从右向左滑动。

如何做到这一点?


当前回答

我知道从2012年开始有点晚了,但我希望它能帮助到一些人,因为我认为它比大多数答案都更短,更干净:

view.setOnTouchListener((v, 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);
}
    });

当然,你可以只留下相关的手势。

src: https://developer.android.com/training/gestures/detector

其他回答

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

现在滚动和滑动动作都可以工作了。

使用SwipeListView,让它为你处理手势检测。

@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方法!

爱德华·布雷的回答在科特林的使用

 view.setOnTouchListener(object: OnSwipeTouchListener(this) {
      override fun onSwipeLeft() {
        super.onSwipeLeft()
      }
      override fun onSwipeRight() {
        super.onSwipeRight()
      }
    }
 )

我一直在做类似的事情,但仅限于水平滑动

import android.content.Context
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View

abstract class OnHorizontalSwipeListener(val context: Context) : View.OnTouchListener {    

    companion object {
         const val SWIPE_MIN = 50
         const val SWIPE_VELOCITY_MIN = 100
    }

    private val detector = GestureDetector(context, GestureListener())

    override fun onTouch(view: View, event: MotionEvent) = detector.onTouchEvent(event)    

    abstract fun onRightSwipe()

    abstract fun onLeftSwipe()

    private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {    

        override fun onDown(e: MotionEvent) = true

        override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float)
            : Boolean {

            val deltaY = e2.y - e1.y
            val deltaX = e2.x - e1.x

            if (Math.abs(deltaX) < Math.abs(deltaY)) return false

            if (Math.abs(deltaX) < SWIPE_MIN
                    && Math.abs(velocityX) < SWIPE_VELOCITY_MIN) return false

            if (deltaX > 0) onRightSwipe() else onLeftSwipe()

            return true
        }
    }
}

然后它可以用于视图组件

private fun listenHorizontalSwipe(view: View) {
    view.setOnTouchListener(object : OnHorizontalSwipeListener(context!!) {
            override fun onRightSwipe() {
                Log.d(TAG, "Swipe right")
            }

            override fun onLeftSwipe() {
                Log.d(TAG, "Swipe left")
            }

        }
    )
}