[android] Android에서 왼쪽 또는 오른쪽으로 스 와이프를 감지하는 방법은 무엇입니까?

나는 EditText안드로이드 에서 볼 수 있습니다. 여기에서 왼쪽이나 오른쪽으로 스 와이프를 감지하고 싶습니다. 아래 코드를 사용하여 빈 공간에 가져올 수 있습니다. 그러나 이것은 EditText. 어떻게하나요? 내가 뭔가 잘못하고 있으면 알려주세요. 감사합니다.

사용 된 코드 :

switch (touchevent.getAction())
{
    case MotionEvent.ACTION_DOWN:
    {
        oldTouchValue = touchevent.getX();
        break;
    }
    case MotionEvent.ACTION_UP:
    {
        float currentX = touchevent.getX();
        if (oldTouchValue < currentX)
        {
            // swiped left
        }
        if (oldTouchValue > currentX )
        {
            swiped right
        }
    break;
    }
}



답변

가장 간단한 왼쪽에서 오른쪽으로 스 와이프 감지기 :

활동 클래스에서 다음 속성을 추가하십시오.

private float x1,x2;
static final int MIN_DISTANCE = 150;

및 재정의 onTouchEvent()방법 :

@Override
public boolean onTouchEvent(MotionEvent event)
{
    switch(event.getAction())
    {
      case MotionEvent.ACTION_DOWN:
          x1 = event.getX();
      break;
      case MotionEvent.ACTION_UP:
          x2 = event.getX();
          float deltaX = x2 - x1;
          if (Math.abs(deltaX) > MIN_DISTANCE)
          {
              Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show ();
          }
          else
          {
              // consider as something else - a screen tap for example
          }
      break;
    }
    return super.onTouchEvent(event);
}


답변

@ user2999943의 코드가 마음에 듭니다. 그러나 내 목적을 위해 약간의 변경이 있습니다.

@Override
public boolean onTouchEvent(MotionEvent event)
{
    switch(event.getAction())
    {
      case MotionEvent.ACTION_DOWN:
          x1 = event.getX();
      break;
      case MotionEvent.ACTION_UP:
          x2 = event.getX();
          float deltaX = x2 - x1;

          if (Math.abs(deltaX) > MIN_DISTANCE)
          {
              // Left to Right swipe action
              if (x2 > x1)
              {
                  Toast.makeText(this, "Left to Right swipe [Next]", Toast.LENGTH_SHORT).show ();
              }

              // Right to left swipe action               
              else
              {
                  Toast.makeText(this, "Right to Left swipe [Previous]", Toast.LENGTH_SHORT).show ();
              }

          }
          else
          {
              // consider as something else - a screen tap for example
          }
      break;
    }
    return super.onTouchEvent(event);
}


답변

이것은 내가 사용하는 귀여운 클래스입니다 (View에서 이벤트를 포착하려는 경우 ViewGroup 인 경우 두 번째 구현을 사용합니다).

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class SwipeDetector implements View.OnTouchListener{

    private int min_distance = 100;
    private float downX, downY, upX, upY;
    private View v;

    private onSwipeEvent swipeEventListener;



    public SwipeDetector(View v){
        this.v=v;
        v.setOnTouchListener(this);
    }

    public void setOnSwipeListener(onSwipeEvent listener)
    {
        try{
            swipeEventListener=listener;
        }
        catch(ClassCastException e)
        {
            Log.e("ClassCastException","please pass SwipeDetector.onSwipeEvent Interface instance",e);
        }
    }


    public void onRightToLeftSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.RIGHT_TO_LEFT);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public void onLeftToRightSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.LEFT_TO_RIGHT);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public void onTopToBottomSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.TOP_TO_BOTTOM);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public void onBottomToTopSwipe(){
        if(swipeEventListener!=null)
            swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.BOTTOM_TO_TOP);
        else
            Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance");
    }

    public boolean onTouch(View v, MotionEvent event) {
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN: {
            downX = event.getX();
            downY = event.getY();
            return true;
        }
        case MotionEvent.ACTION_UP: {
            upX = event.getX();
            upY = event.getY();

            float deltaX = downX - upX;
            float deltaY = downY - upY;

            //HORIZONTAL SCROLL
            if(Math.abs(deltaX) > Math.abs(deltaY))
            {
                if(Math.abs(deltaX) > min_distance){
                    // left or right
                    if(deltaX < 0)
                    {
                        this.onLeftToRightSwipe();
                        return true;
                    }
                    if(deltaX > 0) {
                        this.onRightToLeftSwipe();
                        return true;
                    }
                }
                else {
                    //not long enough swipe...
                    return false;
                }
            }
            //VERTICAL SCROLL
            else
            {
                if(Math.abs(deltaY) > min_distance){
                    // top or down
                    if(deltaY < 0)
                    { this.onTopToBottomSwipe();
                    return true;
                    }
                    if(deltaY > 0)
                    { this.onBottomToTopSwipe();
                    return true;
                    }
                }
                else {
                    //not long enough swipe...
                    return false;
                }
            }

            return true;
        }
        }
        return false;
    }
    public interface onSwipeEvent
    {
        public void SwipeEventDetected(View v, SwipeTypeEnum SwipeType);
    }

    public SwipeDetector setMinDistanceInPixels(int min_distance)
{
    this.min_distance=min_distance;
    return this;
}

    public enum SwipeTypeEnum
    {
        RIGHT_TO_LEFT,LEFT_TO_RIGHT,TOP_TO_BOTTOM,BOTTOM_TO_TOP
    }

}

그리고 이것은 사용 예입니다.

filters_container=(RelativeLayout)root.findViewById(R.id.filters_container);
    new SwipeDetector(filters_container).setOnSwipeListener(new SwipeDetector.onSwipeEvent() {
        @Override
        public void SwipeEventDetected(View v, SwipeDetector.SwipeTypeEnum swipeType) {
            if(swipeType==SwipeDetector.SwipeTypeEnum.LEFT_TO_RIGHT)
                getActivity().onBackPressed();
        }
    });

어떤 경우에는 컨테이너에서 스 와이프 제스처를 감지하고 터치 이벤트를 자식에게 전달하고 싶을 때 사용자 지정보기 그룹을 만들고 RelativeLayout이라고 말하고 onInterceptTouchEvent를 재정의하면 여기에서 스 와이프 이벤트를 감지 할 수 있습니다. 자녀보기에 대한 터치 이벤트 전달을 차단하지 않고 예를 들면 다음과 같습니다.

    import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;


public class SwipeDetectRelativeLayout extends RelativeLayout {


    private float x1,x2;
    static final int MIN_DISTANCE=150;
    private onSwipeEventDetected mSwipeDetectedListener;


    public SwipeDetectRelativeLayout(Context context) {
        super(context);
    }

    public SwipeDetectRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeDetectRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        switch(ev.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                x1 = ev.getX();
                break;
            case MotionEvent.ACTION_UP:
                x2 = ev.getX();
                float deltaX = x2 - x1;
                if (Math.abs(deltaX) > MIN_DISTANCE)
                {
                        //swiping right to left
                        if(deltaX<0)
                        {
                            if(mSwipeDetectedListener!=null)
                                mSwipeDetectedListener.swipeEventDetected();
                        }
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    public interface onSwipeEventDetected
    {
        public void swipeEventDetected();
    }

    public void registerToSwipeEvents(onSwipeEventDetected listener)
    {
        this.mSwipeDetectedListener=listener;
    }
}


답변

스 와이프 이벤트는 일종의 onTouch이벤트입니다. @Gal Rom의 답변을 간단히 단순화하고 수직 및 수평 델타를 추적하고 약간의 수학으로 touchEvent가 어떤 종류의 스 와이프인지 결정할 수 있습니다. (다시 말하지만, 이것은 이전 답변에 근거한 비정상적이지만 단순함은 초보자에게 호소력이있을 수 있습니다). 아이디어는 OnTouchListener를 확장하고 방금 발생한 스 와이프 (터치) 종류를 감지하고 각 종류에 대한 특정 메서드를 호출하는 것입니다.

public class SwipeListener implements View.OnTouchListener {
    private int min_distance = 100;
    private float downX, downY, upX, upY;
    View v;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        this.v = v;
        switch(event.getAction()) { // Check vertical and horizontal touches
            case MotionEvent.ACTION_DOWN: {
                downX = event.getX();
                downY = event.getY();
                return true;
            }
            case MotionEvent.ACTION_UP: {
                upX = event.getX();
                upY = event.getY();

                float deltaX = downX - upX;
                float deltaY = downY - upY;

                //HORIZONTAL SCROLL
                if (Math.abs(deltaX) > Math.abs(deltaY)) {
                    if (Math.abs(deltaX) > min_distance) {
                        // left or right
                        if (deltaX < 0) {
                            this.onLeftToRightSwipe();
                            return true;
                        }
                        if (deltaX > 0) {
                            this.onRightToLeftSwipe();
                            return true;
                        }
                    } else {
                        //not long enough swipe...
                        return false;
                    }
                }
                //VERTICAL SCROLL
                else {
                    if (Math.abs(deltaY) > min_distance) {
                        // top or down
                        if (deltaY < 0) {
                            this.onTopToBottomSwipe();
                            return true;
                        }
                        if (deltaY > 0) {
                            this.onBottomToTopSwipe();
                            return true;
                        }
                    } else {
                        //not long enough swipe...
                        return false;
                    }
                }
                return false;
            }
        }
        return false;
    }

    public void onLeftToRightSwipe(){
        Toast.makeText(v.getContext(),"left to right",
                                      Toast.LENGTH_SHORT).show();
    }

    public void onRightToLeftSwipe() {
        Toast.makeText(v.getContext(),"right to left",
                                     Toast.LENGTH_SHORT).show();
    }

    public void onTopToBottomSwipe() {
        Toast.makeText(v.getContext(),"top to bottom",
                                     Toast.LENGTH_SHORT).show();
    }

    public void onBottomToTopSwipe() {
        Toast.makeText(v.getContext(),"bottom to top",
                                    Toast.LENGTH_SHORT).show();
    }
}


답변

스 와이프 이벤트를 쉽게 감지 할 수있는 간단한 클래스 (위, 오른쪽, 아래, 왼쪽)를 작성했습니다.

1 : 단일 스 와이프 이벤트 감지

// Detect and consume specific events
// {Available methods} - detectTop, detectRight, detectBottom, detectLeft
SwipeEvents.detectTop(swipeElement, new SwipeEvents.SwipeSingleCallback() {
    @Override
    public void onSwipe() {
        showToast("Swiped - detectTop");
    }
});

2 : 하나의 콜백으로 스 와이프 이벤트를 감지합니다.

SwipeEvents.detect( swipeElement, new SwipeEvents.SwipeCallback() {
    @Override
    public void onSwipeTop() {
        //Swiped top
    }

    @Override
    public void onSwipeRight() {
        //Swiped right
    }

    @Override
    public void onSwipeBottom() {
        //Swiped bottom
    }

    @Override
    public void onSwipeLeft() {
        //Swiped left
    }
});

다음은 사용 방법에 대한 설명이 포함 된 블로그 게시물입니다. http://bmutinda.com/android-detect-swipe-events/

또한 https://gist.github.com/bmutinda/9578f70f1df9bd0687b8에서 사용 가능한 코드 스 니펫에 대한 Gist를 만들었습니다.

감사.


답변

왼쪽에서 오른쪽으로, 오른쪽에서 왼쪽으로 스 와이프 감지기

먼저 float 데이터 유형의 두 변수를 선언하십시오.

private float x1, x2;

둘째, Java에서 xml 뷰를 연결합니다. 내가 가진 것처럼ImageView

ImageView img = (ImageView) findViewById(R.id.imageView);

셋째, setOnTouchListenerImageView.

img.setOnTouchListener(
                    new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        // TODO Auto-generated method stub
                        switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            x1 = event.getX();
                            break;
                        case MotionEvent.ACTION_UP:
                            x2 = event.getX();
                            float deltaX = x2 - x1;
                            if (deltaX < 0) {
                                Toast.makeText(MainActivity.this,
                                        "Right to Left swipe",
                                        Toast.LENGTH_SHORT).show();
                            }else if(deltaX >0){
                                Toast.makeText(MainActivity.this,
                                        "Left to Right swipe",
                                        Toast.LENGTH_SHORT).show();
                            }
                            break;
                        }

                        return false;
                    }
                });


답변

부분적으로 작동하지만 시간 변수가 누락되어 완벽하게 만드는 허용되는 답변에 추가하고 싶습니다.

시간 변수가있는 가장 간단한 왼쪽에서 오른쪽으로 스 와이프 감지기 :

활동 클래스에서 다음 속성을 추가하십시오.

private float x1,x2;
private long startClickTime;
static final int MIN_DISTANCE = 150;
static final int MAX_SWIPE_TIME = 200;

onTouchEvent () 메서드를 재정의합니다.

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        switch(event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                startClickTime = Calendar.getInstance().getTimeInMillis();
                x1 = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
                x2 = event.getX();
                float deltaX = x2 - x1;
                if (Math.abs(deltaX) > MIN_DISTANCE && clickDuration < MAX_SWIPE_TIME)
                {
                    Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show ();
                }
                else
                {
                    // consider as something else - a screen tap for example
                }
                break;
        }
        return super.onTouchEvent(event);
    }