首页 文章

Android:如何处理从右到左的滑动手势

提问于
浏览
374

我希望我的应用能够识别用户在手机屏幕上从右向左滑动的时间 .

这该怎么做?

19 回答

  • 5

    OnSwipeTouchListener.java:

    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;
    
    public class OnSwipeTouchListener implements OnTouchListener {
    
        private final GestureDetector gestureDetector;
    
        public OnSwipeTouchListener (Context ctx){
            gestureDetector = new GestureDetector(ctx, new GestureListener());
        }
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    
        private final class GestureListener extends SimpleOnGestureListener {
    
            private static final int SWIPE_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) {
                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) {
                                onSwipeRight();
                            } else {
                                onSwipeLeft();
                            }
                            result = true;
                        }
                    }
                    else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeBottom();
                        } else {
                            onSwipeTop();
                        }
                        result = true;
                    }
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
                return result;
            }
        }
    
        public void onSwipeRight() {
        }
    
        public void onSwipeLeft() {
        }
    
        public void onSwipeTop() {
        }
    
        public void onSwipeBottom() {
        }
    }
    

    用法:

    imageView.setOnTouchListener(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();
        }
    
    });
    
  • 3

    此代码检测左右滑动,避免不推荐使用的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
        }
    });
    
  • 0

    如果您还需要在这里处理点击事件的一些修改:

    public class OnSwipeTouchListener implements OnTouchListener {
    
        private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
    
        public boolean onTouch(final View v, final MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
    
        private final class GestureListener extends SimpleOnGestureListener {
    
            private static final int SWIPE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;
    
    
            @Override
            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) {
                                result = onSwipeRight();
                            } else {
                                result = onSwipeLeft();
                            }
                        }
                    } else {
                        if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffY > 0) {
                                result = onSwipeBottom();
                            } else {
                                result = onSwipeTop();
                            }
                        }
                    }
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
                return result;
            }
        }
    
        public boolean onSwipeRight() {
            return false;
        }
    
        public boolean onSwipeLeft() {
            return false;
        }
    
        public boolean onSwipeTop() {
            return false;
        }
    
        public boolean onSwipeBottom() {
            return false;
        }
    }
    

    样本用法:

    background.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                toggleSomething();
            }
        });
        background.setOnTouchListener(new OnSwipeTouchListener() {
            public boolean onSwipeTop() {
                Toast.makeText(MainActivity.this, "top", Toast.LENGTH_SHORT).show();
                return true;
            }
            public boolean onSwipeRight() {
                Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show();
                return true;
            }
            public boolean onSwipeLeft() {
                Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show();
                return true;
            }
            public boolean onSwipeBottom() {
                Toast.makeText(MainActivity.this, "bottom", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    
  • 732

    您不需要那些复杂的计算 . 只需在 OnGestureListeneronFling 中使用 GestureDetector

    MyGestureListener.java

    import android.util.Log;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    
    public class MyGestureListener implements GestureDetector.OnGestureListener{
    
        private static final long VELOCITY_THRESHOLD = 3000;
    
        @Override
        public boolean onDown(final MotionEvent e){ return false; }
    
        @Override
        public void onShowPress(final MotionEvent e){ }
    
        @Override
        public boolean onSingleTapUp(final MotionEvent e){ return false; }
    
        @Override
        public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX,
                            final float distanceY){ return false; }
    
        @Override
        public void onLongPress(final MotionEvent e){ }
    
        @Override
        public boolean onFling(final MotionEvent e1, final MotionEvent e2,
                           final float velocityX,
                           final float velocityY){
    
            if(Math.abs(velocityX) < VELOCITY_THRESHOLD 
                        && Math.abs(velocityY) < VELOCITY_THRESHOLD){
                return false;//if the fling is not fast enough then it's just like drag
            }
    
            //if velocity in X direction is higher than velocity in Y direction,
            //then the fling is horizontal, else->vertical
            if(Math.abs(velocityX) > Math.abs(velocityY)){
                if(velocityX >= 0){
                    Log.i("TAG", "swipe right");
                }else{//if velocityX is negative, then it's towards left
                    Log.i("TAG", "swipe left");
                }
            }else{
                if(velocityY >= 0){
                    Log.i("TAG", "swipe down");
                }else{
                    Log.i("TAG", "swipe up");
                }
            }
    
            return true;
        }
    }
    

    用法:

    GestureDetector mDetector = new GestureDetector(MainActivity.this, new MyGestureListener());
    
    view.setOnTouchListener(new View.OnTouchListener(){
        @Override
        public boolean onTouch(final View v, final MotionEvent event){
            return mDetector.onTouchEvent(event);
        }
    });
    
  • 0

    扩展Mirek的答案,适用于您想在滚动视图中使用滑动手势的情况 . 默认情况下,滚动视图的触摸侦听器被禁用,因此不会发生滚动操作 . 为了解决这个问题,您需要覆盖 ActivitydispatchTouchEvent 方法,并在完成自己的侦听器后返回此方法的继承版本 .

    为了对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);
    

    并覆盖 Activity 中的 dispatchTouchEvent 方法:

    @Override
        public boolean dispatchTouchEvent(MotionEvent ev){
            swipeListener.getGestureDetector().onTouchEvent(ev); 
                return super.dispatchTouchEvent(ev);   
        }
    

    现在滚动和滑动操作都应该有效 .

  • 8

    要在单 View 上有 Click ListenerDoubleClick ListenerOnLongPress ListenerSwipe LeftSwipe RightSwipe UpSwipe Down ,您需要 setOnTouchListener . 即,

    view.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {
    
                @Override
                public void onClick() {
                    super.onClick();
                    // your on click here
                }
    
                @Override
                public void onDoubleClick() {
                    super.onDoubleClick();
                    // your on onDoubleClick here
                }
    
                @Override
                public void onLongClick() {
                    super.onLongClick();
                    // your on onLongClick here
                }
    
                @Override
                public void onSwipeUp() {
                    super.onSwipeUp();
                    // your swipe up here
                }
    
                @Override
                public void onSwipeDown() {
                    super.onSwipeDown();
                    // your swipe down here.
                }
    
                @Override
                public void onSwipeLeft() {
                    super.onSwipeLeft();
                    // your swipe left here.
                }
    
                @Override
                public void onSwipeRight() {
                    super.onSwipeRight();
                    // your swipe right here.
                }
            });
    
    }
    

    为此,您需要实现 OnTouchListenerOnSwipeTouchListener 类 .

    public class OnSwipeTouchListener implements View.OnTouchListener {
    
    private GestureDetector gestureDetector;
    
    public OnSwipeTouchListener(Context c) {
        gestureDetector = new GestureDetector(c, new GestureListener());
    }
    
    public boolean onTouch(final View view, final MotionEvent motionEvent) {
        return gestureDetector.onTouchEvent(motionEvent);
    }
    
    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
    
        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;
    
        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            onClick();
            return super.onSingleTapUp(e);
        }
    
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            onDoubleClick();
            return super.onDoubleTap(e);
        }
    
        @Override
        public void onLongPress(MotionEvent e) {
            onLongClick();
            super.onLongPress(e);
        }
    
        // Determines the fling velocity and then fires the appropriate swipe event accordingly
        @Override
        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) {
                            onSwipeRight();
                        } else {
                            onSwipeLeft();
                        }
                    }
                } else {
                    if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeDown();
                        } else {
                            onSwipeUp();
                        }
                    }
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }
    
    public void onSwipeRight() {
    }
    
    public void onSwipeLeft() {
    }
    
    public void onSwipeUp() {
    }
    
    public void onSwipeDown() {
    }
    
    public void onClick() {
    
    }
    
    public void onDoubleClick() {
    
    }
    
    public void onLongClick() {
    
    }
    }
    
  • 181

    使用SwipeListView并让它为您处理手势检测 .

    Screenshot

  • 9

    要添加onClick,这就是我所做的 .

    ....
    // in OnSwipeTouchListener class
    
    private final class GestureListener extends SimpleOnGestureListener {
    
        .... // normal GestureListener  code
    
       @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            onClick(); // my method
            return super.onSingleTapConfirmed(e);
        }
    
    } // end GestureListener class
    
        public void onSwipeRight() {
        }
    
        public void onSwipeLeft() {
        }
    
        public void onSwipeTop() {
        }
    
        public void onSwipeBottom() {
        }
    
        public void onClick(){ 
        }
    
    
        // as normal
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
    }
    
    } // end OnSwipeTouchListener class
    

    我正在使用Fragments,所以使用getActivity()作为上下文 . 这就是我实现它的方式 - 它的工作原理 .


    myLayout.setOnTouchListener(new OnSwipeTouchListener(getActivity()) {
                public void onSwipeTop() {
                    Toast.makeText(getActivity(), "top", Toast.LENGTH_SHORT).show();
                }
                public void onSwipeRight() {
                    Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show();
                }
                public void onSwipeLeft() {
                    Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show();
                }
                public void onSwipeBottom() {
                    Toast.makeText(getActivity(), "bottom", Toast.LENGTH_SHORT).show();
                }
    
                public void onClick(){
                    Toast.makeText(getActivity(), "clicked", Toast.LENGTH_SHORT).show();
                }
            });
    
  • 1

    @Edward Brey's method效果很好 . 如果有人还希望复制并粘贴 OnSwipeTouchListener 的导入,那么它们是:

    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;
    
  • 20

    需要一些小的更新 . onTouch方法中的变量不匹配,并且不导入异常类 . 从onFling()返回false更有意义,而不是启动一个变量,为它赋值,不对它做任何事情,只是返回它 .

    onTouch方法的某些部分不正确 . 见view/motionEvent cannot be resolved to a variable swipe

    一个有用的提示可以节省我一些时间,我希望可以帮助其他人:当你使用这个方法时,你只想将“implements”标签添加到你的OnSwipeTouchListener类 . 您的活动和视图未实现它 . 他们只是利用你已经做过的课程!

    1为Mirek,因为他的代码仍然给了我我需要的东西:)

  • 25
    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
            }
    
    
        }
    }
    
  • 3

    对@Mirek Rusin的一点修改回答,现在您可以检测到多点触控滑动 . 这段代码在Kotlin上:

    class OnSwipeTouchListener(ctx: Context, val onGesture: (gestureCode: Int) -> Unit) : OnTouchListener {
    
    private val SWIPE_THRESHOLD = 200
    private val SWIPE_VELOCITY_THRESHOLD = 200
    
    private val gestureDetector: GestureDetector
    
    var fingersCount = 0
    
    fun resetFingers() {
        fingersCount = 0
    }
    
    init {
        gestureDetector = GestureDetector(ctx, GestureListener())
    }
    
    override fun onTouch(v: View, event: MotionEvent): Boolean {
        if (event.pointerCount > fingersCount) {
            fingersCount = event.pointerCount
        }
        return gestureDetector.onTouchEvent(event)
    }
    
    private inner class GestureListener : SimpleOnGestureListener() {
    
        override fun onDown(e: MotionEvent): Boolean {
            return true
        }
    
        override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
            var result = false
            try {
                val diffY = e2.y - e1.y
                val diffX = e2.x - e1.x
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            val gesture = when (fingersCount) {
                                1 -> Gesture.SWIPE_RIGHT
                                2 -> Gesture.TWO_FINGER_SWIPE_RIGHT
                                3 -> Gesture.THREE_FINGER_SWIPE_RIGHT
                                else -> -1
                            }
                            if (gesture > 0) {
                                onGesture.invoke(gesture)
                            }
                        } else {
                            val gesture = when (fingersCount) {
                                1 -> Gesture.SWIPE_LEFT
                                2 -> Gesture.TWO_FINGER_SWIPE_LEFT
                                3 -> Gesture.THREE_FINGER_SWIPE_LEFT
                                else -> -1
                            }
                            if (gesture > 0) {
                                onGesture.invoke(gesture)
                            }
                        }
                        resetFingers()
                    }
                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        val gesture = when (fingersCount) {
                            1 ->  Gesture.SWIPE_DOWN
                            2 -> Gesture.TWO_FINGER_SWIPE_DOWN
                            3 -> Gesture.THREE_FINGER_SWIPE_DOWN
                            else -> -1
                        }
                        if (gesture > 0) {
                            onGesture.invoke(gesture)
                        }
                    } else {
                        val gesture = when (fingersCount) {
                            1 ->  Gesture.SWIPE_UP
                            2 -> Gesture.TWO_FINGER_SWIPE_UP
                            3 -> Gesture.THREE_FINGER_SWIPE_UP
                            else -> -1
                        }
                        if (gesture > 0) {
                            onGesture.invoke(gesture)
                        }
                    }
                    resetFingers()
                }
                result = true
    
            } catch (exception: Exception) {
                exception.printStackTrace()
            }
    
            return result
        }
    }}
    

    其中Gesture.SWIPE_RIGHT和其他人是我用于在我的活动中稍后检测手势类型的手势的唯一整数标识符:

    rootView?.setOnTouchListener(OnSwipeTouchListener(this, {
        gesture -> log(Gesture.parseName(this, gesture))
    }))
    

    所以你看到这里的手势是一个整数变量,它保存我之前传递过的值 .

  • 0

    @Mirek Rusin answeir非常好 . 但是,有一个小错误,需要修复 -

    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,只有在我们检查了所有requrinments(SWIPE_THRESHOLD和SWIPE_VELOCITY_THRESHOLD都是Ok)时才设置 . 如果我们在没有实现某些要求的情况下放弃滑动,这很重要,我们必须在OnSwipeTouchListener的onTouchEvent方法中做smth!

  • 0

    Here is simple Android Code for detecting gesture direction

    MainActivity.javaactivity_main.xml 中,编写以下代码:

    MainActivity.java

    import java.util.ArrayList;
    
    import android.app.Activity;
    import android.gesture.Gesture;
    import android.gesture.GestureLibraries;
    import android.gesture.GestureLibrary;
    import android.gesture.GestureOverlayView;
    import android.gesture.GestureOverlayView.OnGesturePerformedListener;
    import android.gesture.GestureStroke;
    import android.gesture.Prediction;
    import android.os.Bundle;
    import android.widget.Toast;
    
    public class MainActivity extends Activity implements
            OnGesturePerformedListener {
    
        GestureOverlayView gesture;
        GestureLibrary lib;
        ArrayList<Prediction> prediction;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            lib = GestureLibraries.fromRawResource(MainActivity.this,
                    R.id.gestureOverlayView1);
            gesture = (GestureOverlayView) findViewById(R.id.gestureOverlayView1);
            gesture.addOnGesturePerformedListener(this);
        }
    
        @Override
        public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
            ArrayList<GestureStroke> strokeList = gesture.getStrokes();
            // prediction = lib.recognize(gesture);
            float f[] = strokeList.get(0).points;
            String str = "";
    
            if (f[0] < f[f.length - 2]) {
                str = "Right gesture";
            } else if (f[0] > f[f.length - 2]) {
                str = "Left gesture";
            } else {
                str = "no direction";
            }
            Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
    
        }
    
    }
    

    activity_main.xml

    <android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android1="http://schemas.android.com/apk/res/android"
        xmlns:android2="http://schemas.android.com/apk/res/android"
        android:id="@+id/gestureOverlayView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android1:orientation="vertical" >
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Draw gesture"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    
    </android.gesture.GestureOverlayView>
    
  • 2

    我的解决方案与上面的解决方案类似,但我将手势处理抽象为抽象类 OnGestureRegisterListener.java ,其中包括 swipeclicklong click 手势 .

    OnGestureRegisterListener.java

    public abstract class OnGestureRegisterListener implements View.OnTouchListener {
    
        private final GestureDetector gestureDetector;
        private View view;
    
        public OnGestureRegisterListener(Context context) {
            gestureDetector = new GestureDetector(context, new GestureListener());
        }
    
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            this.view = view;
            return gestureDetector.onTouchEvent(event);
        }
    
        public abstract void onSwipeRight(View view);
        public abstract void onSwipeLeft(View view);
        public abstract void onSwipeBottom(View view);
        public abstract void onSwipeTop(View view);
        public abstract void onClick(View view);
        public abstract boolean onLongClick(View view);
    
        private final class GestureListener extends GestureDetector.SimpleOnGestureListener {
    
            private static final int SWIPE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;
    
            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }
    
            @Override
            public void onLongPress(MotionEvent e) {
                onLongClick(view);
                super.onLongPress(e);
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                onClick(view);
                return super.onSingleTapUp(e);
            }
    
            @Override
            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) {
                                onSwipeRight(view);
                            } else {
                                onSwipeLeft(view);
                            }
                            result = true;
                        }
                    }
                    else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeBottom(view);
                        } else {
                            onSwipeTop(view);
                        }
                        result = true;
                    }
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
                return result;
            }
    
        }
    }
    

    并且像这样使用它 . 请注意,您也可以轻松传入 View 参数 .

    OnGestureRegisterListener onGestureRegisterListener = new OnGestureRegisterListener(this) {
        public void onSwipeRight(View view) {
            // Do something
        }
        public void onSwipeLeft(View view) {
            // Do something
        }
        public void onSwipeBottom(View view) {
            // Do something
        }
        public void onSwipeTop(View view) {
            // Do something
        }
        public void onClick(View view) {
            // Do something
        }
        public boolean onLongClick(View view) { 
            // Do something
            return true;
        }
    };
    
    Button button = findViewById(R.id.my_button);
    button.setOnTouchListener(onGestureRegisterListener);
    
  • 0

    最后一个impl只适用于此:

    @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }
    
  • 1

    如果要在滑动列表项时显示一些带有操作的按钮,则互联网上有很多具有此行为的库 . 我实现了我在互联网上找到的图书馆,我非常满意 . 它使用起来非常简单,速度非常快 . 我改进了原始库,并为项目点击添加了一个新的点击监听器 . 此外,我添加了字体真棒库(http://fortawesome.github.io/Font-Awesome/),现在您只需添加一个新的项目 Headers ,并从字体awesome指定图标名称 .

    Here是github链接

  • 1
    public class TranslatorSwipeTouch implements OnTouchListener
    {
       private String TAG="TranslatorSwipeTouch";
    
       @SuppressWarnings("deprecation")
       private GestureDetector detector=new GestureDetector(new TranslatorGestureListener());
    
       @Override
       public boolean onTouch(View view, MotionEvent event)
       {
         return detector.onTouchEvent(event);
       }
    
    private class TranslatorGestureListener extends SimpleOnGestureListener 
    {
        private final int GESTURE_THRESHOULD=100;
        private final int GESTURE_VELOCITY_THRESHOULD=100;
    
        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
    
        @Override
        public boolean onFling(MotionEvent event1,MotionEvent event2,float velocityx,float velocityy)
        {
            try
            {
                float diffx=event2.getX()-event1.getX();
                float diffy=event2.getY()-event1.getY();
    
                if(Math.abs(diffx)>Math.abs(diffy))
                {
                    if(Math.abs(diffx)>GESTURE_THRESHOULD && Math.abs(velocityx)>GESTURE_VELOCITY_THRESHOULD)
                    {
                        if(diffx>0)
                        {
                            onSwipeRight();
                        }
                        else
                        {
                            onSwipeLeft();
                        }
                    }
                }
                else
                {
                    if(Math.abs(diffy)>GESTURE_THRESHOULD && Math.abs(velocityy)>GESTURE_VELOCITY_THRESHOULD)
                    {
                        if(diffy>0)
                        {
                             onSwipeBottom();
                        }
                        else
                        {
                            onSwipeTop();
                        }
                    }
                }
            }
            catch(Exception e)
            {
                Log.d(TAG, ""+e.getMessage());
            }
            return false;           
        }
    
        public void onSwipeRight()
        {
            //Toast.makeText(this.getClass().get, "swipe right", Toast.LENGTH_SHORT).show();
            Log.i(TAG, "Right");
        }
        public void onSwipeLeft()
        {
            Log.i(TAG, "Left");
            //Toast.makeText(MyActivity.this, "swipe left", Toast.LENGTH_SHORT).show();
        }
    
        public void onSwipeTop()
        {
            Log.i(TAG, "Top");
            //Toast.makeText(MyActivity.this, "swipe top", Toast.LENGTH_SHORT).show();
        }
    
        public void onSwipeBottom()
        {
            Log.i(TAG, "Bottom");
            //Toast.makeText(MyActivity.this, "swipe bottom", Toast.LENGTH_SHORT).show();
        }   
    
      }
    
     }
    
  • 46

    在Kotlin中使用Edward Brey's answer

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

相关问题