วิธีตรวจจับการปัดไปทางซ้ายหรือขวาใน Android


93

ฉันมีEditTextมุมมองใน Android ในสิ่งนี้ฉันต้องการตรวจจับการปัดไปทางซ้ายหรือขวา ฉันสามารถรับมันได้ในพื้นที่ว่างโดยใช้รหัสด้านล่าง แต่สิ่งนี้ใช้ไม่ได้เมื่อฉันปัดบน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;
    }
}

บทแนะนำที่เป็นประโยชน์สำหรับข้อกำหนด
amitabha2715

คำตอบ:


111

เครื่องตรวจจับการปัดจากซ้ายไปขวาที่ง่ายที่สุด:

ในคลาสกิจกรรมของคุณเพิ่มแอตทริบิวต์ต่อไปนี้:

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

ขอบคุณที่ใช้งานได้ แต่คุณช่วยบอกวิธีทำให้มันใช้งานได้ถ้ามี scrollView?
LS_

เมื่อgetAction()ส่งคืนข้อมูลผสมของทั้งชนิดการดำเนินการและดัชนีตัวชี้จะไม่ดีกว่าที่จะใช้getActionMasked()ที่ส่งคืนเฉพาะประเภทการกระทำ?
lartkma

โซลูชันนี้ลงวันที่ ตอนนี้คุณสามารถใช้ท่าทาง onFling
Donato

59

ฉันชอบรหัสจาก @ 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);       
}

1
เฮ้ดูเหมือนว่าเมื่อรหัสนี้อยู่ในกิจกรรมที่มี ScrollView จะใช้ไม่ได้ คิดว่าทำไม? เป็นอย่างอื่นรหัสที่ดี
โจนา

Jona มุมมองเดียวกันจะต้องสามารถรับเหตุการณ์ ACTION_DOWN และ ACTION_UP เพื่อให้สามารถใช้งานได้
Al Wang

@AlWang คุณหมายถึงอะไร?
JK

ดูเหมือนว่าในกรณีของ Jona ScrollView กำลังขัดขวาง MotionEvent คุณควรดูที่stackoverflow.com/questions/12884250/…สำหรับการนำไปใช้งาน
Al Wang

คุณช่วยบอกวิธีตรวจจับการปัดขึ้นและลงได้อย่างไร
Maulik

33

นี่เป็นคลาสที่น่ารักที่ฉันใช้ (ในกรณีที่ฉันต้องการจับเหตุการณ์ในมุมมองหากเป็น 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 และที่นั่นคุณสามารถตรวจจับเหตุการณ์การปัดได้ โดยไม่ปิดกั้นการส่งผ่านของ Touch Event ไปยังมุมมองของบุตรหลานของคุณตัวอย่างเช่น

    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 ดังนั้นฉันจึงครอบคลุมก่อนหน้านี้และบนหน้าจอถัดไปขอบคุณ!
ziniestro

@Gal Rom วิธีที่สองใช้ยังไง?
smoothdvd

ตอบโจทย์สุด ๆ ! มันใช้งานได้จริงโดยใช้ความพยายามเพียงเล็กน้อยและมีประสิทธิภาพมาก
xarlymg89

การใช้งานที่ยอดเยี่ยม
Tugrul

9

Swipe events คือเหตุการณ์ประเภท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();
    }
}

3

ฉันเขียนคลาสง่ายๆที่ช่วยให้ตรวจจับเหตุการณ์การปัดได้ง่าย - TOP, RIGHT, BOTTOM, LEFT

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/

ฉันได้สร้าง Gist สำหรับข้อมูลโค้ดที่มีอยู่ที่นี่: https://gist.github.com/bmutinda/9578f70f1df9bd0687b8

ขอบคุณ.


3

จากซ้ายไปขวาและขวาไปซ้าย Swipe Detector

ประการแรกประกาศตัวแปรประเภทข้อมูล float สองตัวแปร

private float x1, x2;

ประการที่สองวางสายมุมมอง xml ของคุณใน java เหมือนที่ฉันมีImageView

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

ประการที่สามsetOnTouchListenerใน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

ฉันต้องการเพิ่มคำตอบที่ยอมรับซึ่งใช้งานได้บางส่วน แต่ไม่มีตัวแปรเวลาซึ่งทำให้สมบูรณ์แบบ

เครื่องตรวจจับการปัดจากซ้ายไปขวาที่ง่ายที่สุดพร้อมตัวแปรเวลา:

ในคลาสกิจกรรมของคุณเพิ่มแอตทริบิวต์ต่อไปนี้:

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

3

ฉันคิดว่าสิ่งที่คุณต้องการเรียกว่าพุ่ง MotionEvents สามารถใช้เพื่อกำหนดทิศทางของการพุ่ง

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

ตรวจจับการปัดสี่ทิศทาง

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

หลังจากทำงานกับฟีเจอร์นี้มาทั้งวันในที่สุดก็ได้คำตอบที่ถูกต้อง

ขั้นแรกให้สร้างคลาสต่อไปนี้:

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

สุดท้ายบนวัตถุที่คุณต้องการใช้ ตัวอย่างของฉัน:

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

โชคดี .


แต่จะคืนกิจกรรมให้ชั้นเรียนได้อย่างไร?
วิเวก

1

หากคุณต้องการจับเหตุการณ์ตั้งแต่เริ่มต้นการปัดคุณสามารถใช้ MotionEvent.ACTION_MOVE และเก็บค่าแรกเพื่อเปรียบเทียบ

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;

            }
        });

สมมติว่าฉันมี Toast เหมือนToast.makeText(MainAcivity.this, "top to down" + increaseValue, Toast.LENGTH_SHORT).show();เธอจะปัดเพียงครั้งเดียวเพื่อเพิ่มค่า min = 0 และ max = 10
sanoj lawrence

1

สิ่งนี้จะช่วยคุณได้ ...

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

เวอร์ชันสั้นและง่าย:

1. สร้างคลาสนามธรรมนี้ก่อน

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. จากนั้นสร้างคลาสที่เป็นรูปธรรมโดยใช้สิ่งที่คุณต้องการ:

public class SwipeListener extends HorizontalSwipeListener {

    public SwipeListener() {
        super(200);
    }

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

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

}

1

นี่คือเครื่องตรวจจับแบบกวาดนิ้วไปทางซ้ายทั่วไปสำหรับมุมมองใด ๆ ใน kotlin โดยใช้ 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
        }
    })
}

จากนั้นนำไปใช้ในเค้าโครงของคุณ:

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

ใช้เฉพาะพิกัด x ที่เพียงพอสำหรับซ้ายไปขวาและในทางกลับกัน
Abhishek

0

คำตอบที่ดีที่สุดคือ @Gal Rom 's มีข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้: แตะเหตุการณ์กลับไปที่มุมมองเด็กก่อน และหากคุณกำหนด onClick หรือ onTouch listener สำหรับพวกเขามุมมอง Parnt (ตัวอย่างเช่นแฟรกเมนต์) จะไม่รับฟังการสัมผัส ดังนั้นหากคุณต้องการกำหนดตัวฟังการปัดสำหรับแฟรกเมนต์ในสถานการณ์นี้คุณต้องใช้มันในคลาสใหม่:

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

ฉันเปลี่ยนคลาสของ @Gal Rom แล้ว ดังนั้นจึงสามารถตรวจจับได้ทั้งการปัดไปทางขวาและซ้ายและโดยเฉพาะอย่างยิ่งมันจะส่งกลับ onInterceptTouchEvent true หลังจากที่ตรวจพบ มันสำคัญเพราะถ้าเราไม่ทำบางครั้งมุมมองของเด็กอาจได้รับเหตุการณ์และทั้งสองอย่างของ Swipe for fragment และ onClick for child view (เช่น) ทำงานและทำให้เกิดปัญหาบางอย่าง หลังจากสร้างคลาสนี้คุณต้องเปลี่ยนไฟล์ xml แฟรกเมนต์ของคุณ:

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

คุณจะเห็นว่าแท็กเริ่มต้นคือคลาสที่เราสร้างขึ้น ตอนนี้อยู่ในคลาส Fragment:

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

ซับซ้อนเล็กน้อย แต่ใช้งานได้ดี :)


0

คุณควรขยายคลาสจากView.OnTouchListenerและจัดการกับonTouchเมธอดโดยการลบล้างคลาส

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

คุณสามารถใช้งานได้อย่างง่ายดายเช่นนี้ในActivityหรือ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()
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.