简体   繁体   English

如何在没有手指抬起的情况下检测滑动事件

[英]How to detect swipe event without finger lift

I want to increment / decrement a number on continuous swipe up / swipe down events. 我想在连续向上滑动/向下滑动事件时递增/递减数字。 I could implement simple swipe events using the GestureDetector and OnSwipeTouchListener. 我可以使用GestureDetector和OnSwipeTouchListener实现简单的滑动事件。

However, this swipe event is sensed only when the finger is lifted after the swipe. 然而,仅在滑动之后抬起手指时才感测到该滑动事件。 So for incrementing the number to +5, I've to make 5 individual swipe up's on the screen. 因此,为了将数字增加到+5,我要在屏幕上进行5次单独向上滑动。

I want to apply 'slider' like action such that the number gets changed while user is swiping up or down anywhere on the screen. 我想应用“滑块”之类的操作,以便在用户在屏幕上的任何位置向上或向下滑动时更改数字。 (I don't want to use the 'Slider' widget). (我不想使用'Slider'小部件)。

Is this possible? 这可能吗?

Any help would be really grateful. 任何帮助都会非常感激。 Thanks! 谢谢!

Use the OnTouchListener: 使用OnTouchListener:

private float baseX, baseY;

OnTouchListener listener = new OnTouchListener(){
    public boolean onTouch (View v, MotionEvent event)
    {
        switch(event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                //TOUCH STARTED
                baseX = event.getX();
                baseY = event.getY();
                return true;
            case MotionEvent.ACTION_MOVE:
                //FINGER IS MOVING
                //Do your calculations here, using the x and y positions relative to the starting values you get in ACTION_DOWN
                return true;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                //TOUCH COMPLETED
                return true;
        }
    }
}

@1up, thanks a lot for the solution! @ 1up,非常感谢解决方案!

An enhancement I could add is even if the swipe direction is reversed without lifting the finger, it would work well. 我可以添加的增强功能即使在不抬起手指的情况下反转滑动方向,它也能正常工作。

Using the skeleton you gave, posting my code hoping it would help somebody in future... 使用您提供的骨架,发布我的代码,希望它将来会帮助某人...

public class OnSwipeListener implements OnTouchListener
{
    @Override
    public boolean onTouch(View v, MotionEvent event) 
    {
    boolean result = false;

    float currentX      = 0.0f;
    float currentY      = 0.0f;

    float current_diffX = 0.0f;
    float current_diffY = 0.0f;

    switch(event.getAction())
    {
        case MotionEvent.ACTION_DOWN:
            //Touch detected, record base X-Y coordinates
            baseX = event.getX();
            baseY = event.getY();

            //As the event is consumed, return true
            result = true;  
            break;

        case MotionEvent.ACTION_MOVE:
            //Swipe started, get current X-Y coordinates and compute those with the base ones
            currentX = event.getX();
            currentY = event.getY();

            current_diffX = currentX - baseX;
            current_diffY = currentY - baseY;

            //...................................................Determine horizontal swipe direction
            if(h_swipe == LEFT_SWIPE)
            {
                if( currentX > previousX )
                {
                    //If here, then horizontal swipe has been reversed
                    h_swipe = RIGHT_SWIPE;

                    //Overwrite base coordinate
                    baseX = previousX;

                    //Recalculate Difference
                    current_diffX = currentX - baseX;
                }
                else
                {
                    //NOP - Intentionally kept empty
                }
            }
            else if(h_swipe == RIGHT_SWIPE)
            {
                if( currentX < previousX )
                {
                    //If here, then horizontal swipe has been reversed
                    h_swipe = LEFT_SWIPE;

                    //Overwrite base coordinate
                    baseX = previousX;

                    //Recalculate Difference
                    current_diffX = currentX - baseX;
                }
                else
                {
                    //NOP - Intentionally kept empty
                }                   
            }
            else
            {
                //If here, then it's a fresh swipe event, so compare with base coordinates
                if( currentX < baseX )
                {
                    h_swipe = LEFT_SWIPE;
                }
                else if( currentX > baseX )
                {
                    h_swipe = RIGHT_SWIPE;
                }
                else
                {
                    //NOP - Intentionally kept empty
                }
            }

            //...................................................Determine vertical swipe direction 
            if(v_swipe == UP_SWIPE)
            {
                if(currentY > previousY)
                {
                    //If here, then vertical swipe has been reversed
                    v_swipe = DOWN_SWIPE;

                    //Overwrite base coordinate
                    baseY = previousY;

                    //Recalculate coordinate difference
                    current_diffY = currentY - baseY;
                }
                else
                {
                    //NOP - Intentionally kept empty
                }
            }
            else if(v_swipe == DOWN_SWIPE)
            {
                if(currentY < previousY)
                {
                    //If here, then vertical swipe has been reversed
                    v_swipe = UP_SWIPE;

                    //Overwrite base coordinate
                    baseY = previousY;

                    //Recalculate coordinate difference
                    current_diffY = currentY - baseY;
                }
                else
                {
                    //NOP - Intentionally kept empty
                }
            }
            else
            {
                //If here, then it's a fresh swipe event, so compare with base coordinates
                if( currentY < baseY )
                {
                    v_swipe = UP_SWIPE;
                }
                else if( currentY > baseY )
                {
                    v_swipe = DOWN_SWIPE;
                }
                else
                {
                    //NOP - Intentionally kept empty
                }
            }

            //Record current coordinates for future comparisons
            previousX = currentX;
            previousY = currentY;

            //................................Determine the prominent swipe (horizontal/vertical)
            if(Math.abs(current_diffX) > Math.abs(current_diffY))
            {
                //It's a horizontal swipe
                if (Math.abs(current_diffX) > SWIPE_THRESHOLD) 
                {
                    if (current_diffX > 0) 
                    {
                        onRightSwipe();
                    } 
                    else 
                    {
                        onLeftSwipe();
                    }
                }
                else
                {
                    //Not enough swipe movement, ignore.
                    //NOP - Intentionally kept empty
                }
            }
            else
            {
                //It's a vertical swipe
                if (Math.abs(current_diffY) > SWIPE_THRESHOLD) 
                {
                    if (current_diffY > 0) 
                    {
                        onDownSwipe();
                    } 
                    else 
                    {
                        onUpSwipe();
                    }
                }
                else
                {
                    //Not enough swipe movement, ignore.
                    //NOP - Intentionally kept empty
                }                   
            }

            //As the event is consumed, return true
            result = true;
            break;

        case MotionEvent.ACTION_UP:
            //Swipe ended, clear variables, if necessary
            h_swipe = NO_H_SWIPE;
            v_swipe = NO_V_SWIPE;

            baseX = 0.0f;
            baseY = 0.0f;

            previousX = 0.0f;
            previousY = 0.0f;

            //As the event is consumed, return true
            result = true;              
            break;

        default:

            //Do not consume event
            result = false;
            break;
    }

    return result;
}


public void onUpSwipe()
{

}

public void onDownSwipe()
{

}

public void onRightSwipe()
{

}

public void onLeftSwipe()
{

}
}

So i wrote my own version of direction listener. 所以我写了自己的方向听众版本。


NOTE : IT TELLS YOU ABOUT THE DIRECTION OF SWIPE ON A CONTINUOUS TOUCH SESSION! 注意:在连续的触摸会话中告诉您关于SWIPE的方向!

import android.view.MotionEvent;
import android.view.View;

public class SwipeDirectionListener implements View.OnTouchListener {

float deltaX ;
float deltaY ;
float maxValX;
float maxValY;
float firstTouchX;
float firstTouchY;
float currentX ;
float currentY ;
float SWIPE_THRESHOLD = 10.0f;

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

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //Register the first touch on TouchDown and this should not change unless finger goes up.
            firstTouchX = event.getX();
            firstTouchY = event.getY();
            maxValX = 0.0f;
            maxValY = 0.0f;
            //As the event is consumed, return true
            result = true;
            break;

        case MotionEvent.ACTION_MOVE:
            //CurrentX/Y are the continues changing values of one single touch session. Change
            //when finger slides on view
            currentX = event.getX();
            currentY = event.getY();
           //setting the maximum value of X or Y so far. Any deviation in this means a  change of direction so reset the firstTouch value to last known max value i.e MaxVal X/Y.
            if(maxValX <currentX){
                maxValX = currentX;
            }else{
                firstTouchX= maxValX;
                maxValX =0.0f;
            }

            if(maxValY <currentY){
                maxValY = currentY;
            }else{
                firstTouchY= maxValY;
                maxValY =0.0f;
            }
            //DeltaX/Y are the difference between current touch and the value when finger first touched screen.
            //If its negative that means current value is on left side of first touchdown value i.e Going left and
            //vice versa.
            deltaX = currentX - firstTouchX;
            deltaY = currentY - firstTouchY;

            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                //Horizontal swipe
                if (Math.abs(deltaX) > SWIPE_THRESHOLD) {
                    if (deltaX > 0) {
                        //means we are going right
                        onRightSwipe(currentX);
                    } else {
                        //means we are going left
                        onLeftSwipe(currentX);
                    }
                } 
            } else {
                //It's a vertical swipe
                if (Math.abs(deltaY) > SWIPE_THRESHOLD) {
                    if (deltaY > 0) {
                        //means we are going down
                        onDownSwipe(currentY);
                    } else {
                        //means we are going up
                        onUpSwipe(currentY);
                    }
                } 
            }

            result = true;
            break;

        case MotionEvent.ACTION_UP:
            //Clean UP
            firstTouchX = 0.0f;
            firstTouchY = 0.0f;

            result = true;
            break;

        default:
            result = false;
            break;
    }

    return result;
}


public void onUpSwipe(float value) {

}

public void onDownSwipe(float value) {

}

public void onRightSwipe(float value) {

}

public void onLeftSwipe(float value) {

}
}

And that works like a charm! 这就像一个魅力!

Implementation: 执行:

yourView.setOnTouchListener(new SwipeDirectionListener() {
        public void onUpSwipe(float value) {

            mTextView.setText("onUpSwipe :"+value);
        }

        public void onDownSwipe(float value) {
            mTextView.setText("onDownSwipe :"+value);
        }

        public void onRightSwipe(float value) {
            mTextView.setText("onRightSwipe :"+value);
        }

        public void onLeftSwipe(float value) {
            mTextView.setText("onLeftSwipe :"+value);
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM