Làm thế nào để phát hiện vuốt sang trái hoặc phải trong Android?


93

Tôi có một EditTextcái nhìn trong android. Trên này, tôi muốn phát hiện vuốt sang trái hoặc phải. Tôi có thể lấy nó trên một không gian trống bằng cách sử dụng mã bên dưới. Nhưng điều này không hoạt động khi tôi vuốt trên một EditText. Làm thế nào để làm điều đó? Vui lòng cho tôi biết nếu tôi đang làm điều gì đó sai trái. Cảm ơn bạn.

Mã đã được sử dụng:

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;
    }
}

Hướng dẫn hữu ích cho yêu cầu này techrepublic.com/blog/software-engineer/…
amitabha2715

Câu trả lời:


111

Trình phát hiện vuốt từ trái sang phải đơn giản nhất:

Trong lớp hoạt động của bạn, hãy thêm các thuộc tính sau:

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

và ghi đè onTouchEvent()phương pháp:

@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);        
}

cảm ơn nó hoạt động nhưng bạn có thể vui lòng cho tôi biết làm thế nào để làm cho nó hoạt động nếu có một scrollView?
LS_

Khi getAction()trả về dữ liệu hỗn hợp của cả loại hành động và chỉ mục con trỏ, sẽ không tốt hơn nếu sử dụng getActionMasked(), điều đó chỉ trả về loại hành động?
lartkma

Giải pháp này là ngày. Bây giờ bạn có thể sử dụng cử chỉ onFling.
Donato

59

Tôi thích mã từ @ user2999943. Nhưng chỉ là một số thay đổi nhỏ cho mục đích của riêng tôi.

@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);       
}

1
Này, có vẻ như khi mã này ở trong một hoạt động với ScrollView, nó không hoạt động. Bất kỳ ý tưởng tại sao? Mã tuyệt vời nếu không
Jona

Jona, cùng một Chế độ xem phải có thể nhận các sự kiện ACTION_DOWN và ACTION_UP để điều này hoạt động.
Al Wang

@AlWang ý bạn là gì?
JK

Có vẻ như trong trường hợp của Jona, ScrollView đang chặn MotionEvent. Bạn nên xem stackoverflow.com/questions/12884250/… để biết cách triển khai.
Al Wang

bạn có thể cho tôi biết làm thế nào để phát hiện lên xuống swipe cũng
Maulik

33

Đây là một lớp dễ thương mà tôi sử dụng (trong trường hợp tôi muốn bắt sự kiện trên một Chế độ xem, nếu đó là một Nhóm xem, tôi sử dụng triển khai thứ hai):

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
    }

}

và đây là một ví dụ sử dụng:

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();
        }
    });

Trong một số trường hợp, bạn muốn phát hiện các cử chỉ vuốt trên vùng chứa và chuyển Sự kiện chạm cho trẻ em để trong trường hợp đó, bạn có thể tạo nhóm Chế độ xem tùy chỉnh, giả sử như RelativeLayout và ghi đè onInterceptTouchEvent và ở đó bạn có thể phát hiện sự kiện vuốt mà không chặn việc chuyển Sự kiện chạm tới các chế độ xem của con bạn, ví dụ:

    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;
    }
}

triển khai tuyệt vời, tôi đã sử dụng tùy chọn đầu tiên và cũng đã thêm hỗ trợ cho onTouch, vì vậy tôi đã đề cập đến phần trước và onTouch tiếp theo, cảm ơn!
ziniestro

@Gal Rom Làm thế nào để sử dụng phương pháp thứ hai?
Smoothdvd

Câu trả lời xuất sắc! Nó chắc chắn hoạt động với rất ít nỗ lực và siêu hiệu quả.
xarlymg89

Cách triển khai tuyệt vời.
Tugrul

9

Sự kiện vuốt là một loại onTouchsự kiện. Đơn giản hóa câu trả lời của @Gal Rom, chỉ cần theo dõi chiều dọc và ngang, và với một chút toán học, bạn có thể xác định kiểu vuốt touchEvent. (Một lần nữa, hãy để tôi nhấn mạnh rằng điều này HOÀN TOÀN dựa trên câu trả lời trước đó, nhưng sự đơn giản có thể thu hút những người mới làm quen). Ý tưởng là mở rộng OnTouchListener, phát hiện kiểu vuốt (chạm) nào vừa xảy ra và gọi các phương thức cụ thể cho từng loại.

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();
    }
}

3

Tôi đã viết một lớp đơn giản giúp dễ dàng phát hiện các sự kiện vuốt - ĐẦU, PHẢI, ĐÁY, TRÁI.

1: Phát hiện một sự kiện vuốt

// 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: Phát hiện bất kỳ sự kiện vuốt nào bằng một lần gọi lại.

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

Đây là một bài đăng trên blog với giải thích về cách sử dụng: http://bmutinda.com/android-detect-swipe-events/

Tôi cũng đã tạo Gist cho các đoạn mã có sẵn tại đây: https://gist.github.com/bmutinda/9578f70f1df9bd0687b8

Cảm ơn.


3

Bộ phát hiện vuốt từ trái sang phải và từ phải sang trái

Đầu tiên, khai báo hai biến kiểu dữ liệu float.

private float x1, x2;

Thứ hai, wireup chế độ xem xml của bạn trong java. Như tôi cóImageView

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

Thứ ba, setOnTouchListenervề của bạn ImageView.

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

3

Tôi muốn thêm vào câu trả lời được chấp nhận có tác dụng một phần, nhưng thiếu biến thời gian, điều đó làm cho nó trở nên hoàn hảo.

Trình phát hiện vuốt từ trái sang phải đơn giản nhất với biến thời gian:

Trong lớp hoạt động của bạn, hãy thêm các thuộc tính sau:

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

và ghi đè phương thức 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);
    }

3

Tôi nghĩ những gì bạn muốn được gọi là một cú ném. MotionEvents có thể được sử dụng để xác định hướng bay.

public class MainActivity extends Activity implements  GestureDetector.OnGestureListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stellar_layout);
        mDetector = new GestureDetectorCompat(this, this);
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2,
                           float velocityX, float velocityY) {
        Log.d(tag, "onFling:\n " + event1.toString()+ "\n " + event2.toString());
        /* prints the following
            MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=297.0, y[0]=672.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=488341979, downTime=488341979, deviceId=6, source=0x1002 }
            MotionEvent { action=ACTION_UP, id[0]=0, x[0]=560.0, y[0]=583.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=488342047, downTime=488341979, deviceId=6, source=0x1002 }
        */
        return true;
    }

}

http://developer.android.com/training/gestures/detector.html


2

Phát hiện vuốt theo bốn hướng

private float x1,x2,y1,y2;
static final int MIN_DISTANCE = 70;

switch(pSceneTouchEvent.getAction())
     {
       case MotionEvent.ACTION_DOWN:
           x1 = pSceneTouchEvent.getX();     
           y1 = pSceneTouchEvent.getY();
       break;         
       case MotionEvent.ACTION_UP:
           x2 = pSceneTouchEvent.getX();
           y2 = pSceneTouchEvent.getY();
           float deltaX = x2 - x1;
           float deltaY = y2 - y1;
           if (deltaX > MIN_DISTANCE)
           {
               swipeLeftToRight();
           }
           else if( Math.abs(deltaX) > MIN_DISTANCE)
           {
               swipeRightToLeft();
           } 
           else if(deltaY > MIN_DISTANCE){
               swipeTopToBottom();
           } 
           else if( Math.abs(deltaY) > MIN_DISTANCE){
               swipeBottopmToTop();
           }

       break;   
     }          

2

Sau cả ngày làm việc trên tính năng này cuối cùng cũng có thể nhận được câu trả lời đúng.

Đầu tiên, tạo các lớp sau:

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

/**
 * Created by hoshyar on 1/19/17.
 */

public class SwipeDetector implements View.OnTouchListener {

    public static enum Action {
        LR, // Left to Right
        RL, // Right to Left
        TB, // Top to bottom
        BT, // Bottom to Top
        None // when no action was detected
    }

    private static final String logTag = "Swipe";
    private static final int MIN_DISTANCE = 100;
    private float downX, downY, upX, upY;
    private Action mSwipeDetected = Action.None;

    public boolean swipeDetected() {
        return mSwipeDetected != Action.None;
    }

    public Action getAction() {
        return mSwipeDetected;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                mSwipeDetected = Action.None;
                return false;

            case MotionEvent.ACTION_MOVE:
                upX = event.getX();
                upY = event.getY();

                float deltaX = downX - upX;
                float deltaY = downY - upY;
                Log.i(logTag,String.valueOf(deltaX));
                Log.i(logTag,String.valueOf(deltaX));

                if (deltaY>0 && deltaY<10 && deltaX<0 || deltaY==0 && deltaX>-15 && deltaX<0){
                    Log.i(logTag,"to right");
                }if (deltaY>=0 && deltaY<10 && deltaX>0 || deltaY<0 && deltaX>15 && deltaX<40){
                Log.i(logTag,"to left");
            }





                if (Math.abs(deltaX) > MIN_DISTANCE) {
                    // left or right
                    if (deltaX < 0) {
                        mSwipeDetected = Action.LR;
                        return false;
                    }
                    if (deltaX > 0) {


                        mSwipeDetected = Action.RL;
                        return false;
                    }
                } else if (Math.abs(deltaY) > MIN_DISTANCE) {


                    if (deltaY < 0) {
                        Log.i(logTag,"to bottom");
                        mSwipeDetected = Action.TB;
                        return false;
                    }
                    if (deltaY > 0) {
                        Log.i(logTag,"to up");
                        mSwipeDetected = Action.BT;
                        return false;
                    }
                }
                return true;
        }
        return false;
    }
}

Cuối cùng trên đối tượng mà bạn muốn áp dụng. Ví dụ của tôi:

SwipeDetector swipeDetector = new SwipeDetector();
listView.setOnTouchListener(swipeDetector);

Chúc may mắn .


nhưng làm thế nào để trả lại sự kiện cho lớp?
Vivek

1

Nếu bạn muốn nắm bắt sự kiện từ khi bắt đầu vuốt, bạn có thể sử dụng MotionEvent.ACTION_MOVE và lưu trữ giá trị đầu tiên để so sánh

private float upX1;
private float upX2;
private float upY1;
private float upY2;
private boolean isTouchCaptured = false;
static final int min_distance = 100;


        viewObject.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_MOVE: {
                        downX = event.getX();
                        downY = event.getY();

                        if (!isTouchCaptured) {
                            upX1 = event.getX();
                            upY1 = event.getY();
                            isTouchCaptured = true;
                        } else {
                            upX2 = event.getX();
                            upY2 = event.getY();

                            float deltaX = upX1 - upX2;
                            float deltaY = upY1 - upY2;
                            //HORIZONTAL SCROLL
                            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                                if (Math.abs(deltaX) > min_distance) {
                                    // left or right
                                    if (deltaX < 0) {

                                        return true;
                                    }
                                    if (deltaX > 0) {
                                        return true;
                                    }
                                } else {
                                    //not long enough swipe...
                                    return false;
                                }
                            }
                            //VERTICAL SCROLL
                            else {
                                if (Math.abs(deltaY) > min_distance) {
                                    // top or down
                                    if (deltaY < 0) {

                                        return false;
                                    }
                                    if (deltaY > 0) {

                                        return false;
                                    }
                                } else {
                                    //not long enough swipe...
                                    return false;
                                }
                            }
                        }
                        return false;
                    }
                    case MotionEvent.ACTION_UP: {
                        isTouchCaptured = false;
                    }
                }
                return false;

            }
        });

giả sử tôi có một Bánh mì nướng như Toast.makeText(MainAcivity.this, "top to down" + increaseValue, Toast.LENGTH_SHORT).show();cô ấy, làm thế nào để thực hiện một lần vuốt để thêm các giá trị min = 0 và max = 10.
sanoj lawrence

1

điều này sẽ giúp bạn có thể ...

private final GestureDetector.SimpleOnGestureListener onGestureListener = new GestureDetector.SimpleOnGestureListener() {
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.i("gestureDebug333", "doubleTapped:" + e);
        return super.onDoubleTap(e);
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        Log.i("gestureDebug333", "doubleTappedEvent:" + e);

        return super.onDoubleTapEvent(e);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        Log.i("gestureDebug333", "onDown:" + e);


        return super.onDown(e);

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {


        Log.i("gestureDebug333", "flinged:" + e1 + "---" + e2);
        Log.i("gestureDebug333", "fling velocity:" + velocityX + "---" + velocityY);
        if (e1.getAction() == MotionEvent.ACTION_DOWN && e1.getX() > (e2.getX() + 300)){
           // Toast.makeText(context, "flinged right to left", Toast.LENGTH_SHORT).show();
            goForward();
        }
        if (e1.getAction() == MotionEvent.ACTION_DOWN && e2.getX() > (e1.getX() + 300)){
            //Toast.makeText(context, "flinged left to right", Toast.LENGTH_SHORT).show();
            goBack();
        }
        return super.onFling(e1, e2, velocityX, velocityY);
    }

    @Override
    public void onLongPress(MotionEvent e) {
        super.onLongPress(e);
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return super.onScroll(e1, e2, distanceX, distanceY);
    }

    @Override
    public void onShowPress(MotionEvent e) {
        super.onShowPress(e);
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        return super.onSingleTapConfirmed(e);
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return super.onSingleTapUp(e);
    }
};

1

Phiên bản ngắn và dễ dàng:

1. Đầu tiên hãy tạo lớp trừu tượng này

public abstract class HorizontalSwipeListener implements View.OnTouchListener {

    private float firstX;
    private int minDistance;

    HorizontalSwipeListener(int minDistance) {
        this.minDistance = minDistance;
    }

    abstract void onSwipeRight();

    abstract void onSwipeLeft();

    @Override
    public boolean onTouch(View view, MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                firstX = event.getX();
                return true;
            case MotionEvent.ACTION_UP:
                float secondX = event.getX();
                if (Math.abs(secondX - firstX) > minDistance) {
                    if (secondX > firstX) {
                        onSwipeLeft();
                    } else {
                        onSwipeRight();
                    }
                }
                return true;
        }
        return view.performClick();
    }

}

2.Sau đó, tạo một lớp cụ thể thực hiện những gì bạn cần:

public class SwipeListener extends HorizontalSwipeListener {

    public SwipeListener() {
        super(200);
    }

    @Override
    void onSwipeRight() {
        System.out.println("right");
    }

    @Override
    void onSwipeLeft() {
        System.out.println("left");
    }

}

1

đây là trình phát hiện vuốt sang trái chung cho bất kỳ chế độ xem nào trong kotlin bằng cách sử dụng databinding

@BindingAdapter("onSwipeLeft")
fun View.setOnSwipeLeft(runnable: Runnable) {
    setOnTouchListener(object : View.OnTouchListener {
        var x0 = 0F; var y0 = 0F; var t0 = 0L
        val defaultClickDuration = 200

        override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
            motionEvent?.let { event ->
                when(event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        x0 = event.x; y0 = event.y; t0 = System.currentTimeMillis()
                    }
                    MotionEvent.ACTION_UP -> {
                        val x1 = event.x; val y1 = event.y; val t1 = System.currentTimeMillis()

                        if (x0 == x1 && y0 == y1 && (t1 - t0) < defaultClickDuration) {
                            performClick()
                            return false
                        }
                        if (x0 > x1) { runnable.run() }
                    }
                    else -> {}
                }
            }
            return true
        }
    })
}

và sau đó để sử dụng nó trong bố cục của bạn:

app:onSwipeLeft="@{() -> viewModel.swipeLeftHandler()}"

0
public class TransferMarket extends Activity {

    float x1,x2;
    float y1, y2;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_transfer_market);
    }

    // onTouchEvent () method gets called when User performs any touch event on screen

    // Method to handle touch event like left to right swap and right to left swap

    public boolean onTouchEvent(MotionEvent touchevent)
    {
        switch (touchevent.getAction())
        {
            // when user first touches the screen we get x and y coordinate
            case MotionEvent.ACTION_DOWN:
            {
                x1 = touchevent.getX();
                y1 = touchevent.getY();
                break;
            }
            case MotionEvent.ACTION_UP:
            {
                x2 = touchevent.getX();
                y2 = touchevent.getY();

                //if left to right sweep event on screen
                if (x1 < x2)
                {
                    Toast.makeText(this, "Left to Right Swap Performed", Toast.LENGTH_LONG).show();
                }

                // if right to left sweep event on screen
                if (x1 > x2)
                {
                    Toast.makeText(this, "Right to Left Swap Performed", Toast.LENGTH_LONG).show();
                }

                // if UP to Down sweep event on screen
                if (y1 < y2)
                {
                    Toast.makeText(this, "UP to Down Swap Performed", Toast.LENGTH_LONG).show();
                }

                //if Down to UP sweep event on screen
                if (y1 > y2)
                {
                    Toast.makeText(this, "Down to UP Swap Performed", Toast.LENGTH_LONG).show();
                }
                break;
            }
        }
        return false;
    }

Chỉ sử dụng tọa độ Chỉ x đủ cho từ trái sang phải và ngược lại
Abhishek

0

câu trả lời tốt nhất là @Gal Rom 's. có thêm thông tin về nó: trước tiên hãy chạm vào sự kiện quay lại chế độ xem con. và nếu bạn xác định trình nghe onClick hoặc onTouch cho chúng, chế độ xem parnt (ví dụ: phân đoạn) sẽ không nhận được bất kỳ trình nghe cảm ứng nào. Vì vậy, nếu bạn muốn xác định trình nghe vuốt cho phân đoạn trong tình huống này, bạn phải triển khai nó trong một lớp mới:

    package com.neganet.QRelations.fragments;

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

public class SwipeListenerFragment extends FrameLayout {
    private float x1,x2;
    static final int MIN_DISTANCE=150;
    private onSwipeEventDetected mSwipeDetectedListener;


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

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean result=false;
        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)
                {
                    if(deltaX<0)
                    {
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeLeftDetected();

                    }else if(deltaX>0){
                        result=true;
                        if(mSwipeDetectedListener!=null)
                            mSwipeDetectedListener.swipeRightDetected();
                    }
                }
                break;
        }
        return result;
    }

    public interface onSwipeEventDetected
    {
        public void swipeLeftDetected();
        public void swipeRightDetected();

    }

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

Tôi đã thay đổi lớp của @Gal Rom. Vì vậy, nó có thể phát hiện cả vuốt phải và vuốt trái và đặc biệt nó trả về onInterceptTouchEvent true sau khi phát hiện. nó quan trọng bởi vì nếu chúng ta không làm điều đó, một số lần các chế độ xem con có thể nhận được sự kiện và cả hai ứng dụng Swipe cho phân mảnh và onClick cho chế độ xem con (ví dụ) chạy và gây ra một số sự cố. sau khi tạo lớp này, bạn phải thay đổi tệp xml phân mảnh của mình:

    <com.neganet.QRelations.fragments.SwipeListenerFragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:id="@+id/main_list_layout"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:layout_height="match_parent" tools:context="com.neganet.QRelations.fragments.mainList"
    android:background="@color/main_frag_back">

    <!-- TODO: Update blank fragment layout -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/farazList"
        android:scrollbars="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="left|center_vertical" />
</com.neganet.QRelations.fragments.SwipeListenerFragment>

bạn thấy rằng thẻ bắt đầu là lớp mà chúng tôi đã tạo. bây giờ trong lớp phân mảnh:

            View view=inflater.inflate(R.layout.fragment_main_list, container, false);
        SwipeListenerFragment tdView=(SwipeListenerFragment) view;
        tdView.registerToSwipeEvents(this);


and then Implement SwipeListenerFragment.onSwipeEventDetected in it:

        @Override
    public void swipeLeftDetected() {
        Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void swipeRightDetected() {
        Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show();
    }

Nó hơi phức tạp nhưng hoạt động hoàn hảo :)


0

Bạn nên mở rộng một lớp từ View.OnTouchListenervà xử lý onTouchphương thức bằng cách ghi đè nó.

interface SwipeListener {
    fun onSwipeLeft()
    fun onSwipeRight()
}

class SwipeGestureListener internal constructor(
    private val listener: SwipeListener,
    private val minDistance: Int = DEFAULT_SWIPE_MIN_DISTANCE
) : View.OnTouchListener {
    companion object {
        const val DEFAULT_SWIPE_MIN_DISTANCE = 200
    }

    private var anchorX = 0F

    override fun onTouch(view: View, event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                anchorX = event.x
                return true
            }
            MotionEvent.ACTION_UP -> {
                if (abs(event.x - anchorX) > minDistance) {
                    if (event.x > anchorX) {
                        listener.onSwipeRight()
                    } else {
                        listener.onSwipeLeft()
                    }
                }
                return true
            }
        }
        return view.performClick()
    }
}

Bạn có thể dễ dàng thực hiện nó như thế này trong của bạn Activityhoặc Fragment.

class MainActivity : AppCompatActivity(), SwipeListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewGroup.setOnTouchListener(SwipeGestureListener(this))
    }

    override fun onSwipeLeft() {
        Toast.makeText(this, "Swipe Left", Toast.LENGTH_SHORT).show()
    }

    override fun onSwipeRight() {
        Toast.makeText(this, "Swipe Right", Toast.LENGTH_SHORT).show()
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.