एंड्रॉइड: राइट टू लेफ्ट स्वाइप जेस्चर कैसे हैंडल करें


442

मैं चाहता हूं कि मेरा ऐप तब पहचाने जब कोई उपयोगकर्ता फ़ोन स्क्रीन पर दाईं से बाईं ओर स्वाइप करे।

यह कैसे करना है?


1
इस लिंक को देखें stackoverflow.com/questions/937313/…
Falmarri

ऊपर / नीचे / बाएँ / दाएँ स्वाइप जेस्चर stackoverflow.com/questions/13095494/…
fernandohur

मेरे पुस्तकालय की जाँच करें जो सहायक हो सकता है github.com/UdiOshi85/libSwipes
उडी ओशी

1
यहाँ
कोटलिन

जवाबों:


840

OnSwipeTouchListener.java :

import android.content.Context;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class OnSwipeTouchListener implements OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener (Context ctx){
        gestureDetector = new GestureDetector(ctx, new GestureListener());
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

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

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight();
                        } else {
                            onSwipeLeft();
                        }
                        result = true;
                    }
                }
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom();
                    } else {
                        onSwipeTop();
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public void onSwipeRight() {
    }

    public void onSwipeLeft() {
    }

    public void onSwipeTop() {
    }

    public void onSwipeBottom() {
    }
}

उपयोग:

imageView.setOnTouchListener(new OnSwipeTouchListener(MyActivity.this) {
    public void onSwipeTop() {
        Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeRight() {
        Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeLeft() {
        Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeBottom() {
        Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
    }

});

6
महान काम करता है, लेकिन सुपर। टच (देखें, गति); मुझे ग्रहण में त्रुटि की चेतावनी देता है "प्रकार वस्तु के लिए अपरिभाषित है"। इस काम को हटाना बहुत अच्छा है।
ओपियोटेफच्स

22
धन्यवाद एक आकर्षण की तरह काम करता है लेकिन आपको एक कंस्ट्रक्टर को जोड़ना चाहिए OnSwipeTouchListenerजो एक संदर्भ प्राप्त करता है क्योंकि वह कंस्ट्रक्टर GestureDetectorएपीआई स्तर 3 के बाद से हटा दिया गया है, और GestureDetectorउस कंस्ट्रक्टर में तुरंत काम करता है।
ह्यूगो अल्वेस

9
यह मेरे लिए इन संशोधनों के साथ काम करने के लिए धन्यवाद: stackoverflow.com/a/19506010/401403
Arash

3
लेकिन "ऑनडाउन" कभी नहीं कहा जाता है। एक परिणाम के रूप में, मेरा e1 हमेशा शून्य है और मैं इसके बारे में कुछ नहीं कर सकता।
मंगलगीत

3
इस उत्तर के लिए मेरा फिक्स परिभाषा onTouchमें स्थानांतरित करना है OnSwipeTouchListener, अन्यथा मेरी आईडीई "निजी सदस्य तक पहुंच" त्रुटि को पॉप करेगी
जीई रोंग

199

यह कोड बाएं और दाएं स्वाइप का पता लगाता है, अपग्रेडेड एपीआई कॉल से बचा जाता है, और पहले के उत्तरों पर अन्य विविध सुधार होते हैं।

/**
 * Detects left and right swipes across a view.
 */
public class OnSwipeTouchListener implements OnTouchListener {

    private final GestureDetector gestureDetector;

    public OnSwipeTouchListener(Context context) {
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    public void onSwipeLeft() {
    }

    public void onSwipeRight() {
    }

    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_DISTANCE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

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

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            float distanceX = e2.getX() - e1.getX();
            float distanceY = e2.getY() - e1.getY();
            if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                if (distanceX > 0)
                    onSwipeRight();
                else
                    onSwipeLeft();
                return true;
            }
            return false;
        }
    }
}

इसे इस तरह उपयोग करें:

view.setOnTouchListener(new OnSwipeTouchListener(context) {
    @Override
    public void onSwipeLeft() {
        // Whatever
    }
});

12
@ जोना आप निश्चित रूप से एंड्रॉइड फंडामेंटल पर एक अच्छी किताब या अन्य संसाधन प्राप्त करना चाहेंगे; अन्यथा, StackOverflow से एक साथ कोबल्स समाधान की कोशिश करना निराशाजनक साबित होगा। एक अच्छा विकल्प एंड्रॉइड डेवलपर्स के लिए आधिकारिक प्रशिक्षण हैगतिविधि शुरू करने वाला खंड आपके बारे में बताता है कि आप कहां setOnTouchListener(आमतौर पर onCreate) डालेंगे । contextहै thisसूचक (जब तक आप एक टुकड़ा बना रहे हैं)।
एडवर्ड ब्रे

3
@ लारा, मैंने यह कोशिश नहीं की है, लेकिन आप SimpleOnGestureListener.onSingleTapConfirmed को ओवरराइड करने की कोशिश कर सकते हैं ।
एडवर्ड ब्रे जूल

4
धन्यवाद, एडवर्ड। मैंने यह भी पाया कि ऑनडाउन की वापसी को सच्चे से असत्य में बदलने से चाल चली जाती है।
लारा

2
@ सिग्नो, दृश्य युक्त गतिविधि संदर्भ प्रदान करती है। एक टुकड़े में दृश्य जोड़ने के सामान्य मामले में, उपयोग करें Fragment.getActivity()
एडवर्ड ब्रे डे

2
@coderVishal आपके उद्देश्य के आधार पर, आप उपयोगी SwipeRefreshLayout , SwipeRefreshLayoutBasic नमूना या इसके किसी एक संस्करण को देख सकते हैं।
एडवर्ड ब्रे

49

यदि आपको कुछ संशोधनों के लिए यहां क्लिक की घटनाओं को संसाधित करने की आवश्यकता है:

public class OnSwipeTouchListener implements OnTouchListener {

    private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());

    public boolean onTouch(final View v, final MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    private final class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;


        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            result = onSwipeRight();
                        } else {
                            result = onSwipeLeft();
                        }
                    }
                } else {
                    if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            result = onSwipeBottom();
                        } else {
                            result = onSwipeTop();
                        }
                    }
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public boolean onSwipeRight() {
        return false;
    }

    public boolean onSwipeLeft() {
        return false;
    }

    public boolean onSwipeTop() {
        return false;
    }

    public boolean onSwipeBottom() {
        return false;
    }
}

और नमूना उपयोग:

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

5
मुझे आपके संशोधित OnSwipeTouchListener में आसानी से संशोधन दिखाई नहीं देता है। वास्तव में वह कहाँ है ?
निकोलस जोजोल

5
यह स्वीकृत उत्तर होना चाहिए ... अंतर सूक्ष्म लेकिन बहुत महत्वपूर्ण हैं। पहला, कोई ऑनडाउन () नहीं है। दूसरे, हैंडलर यह संकेत देने के लिए बूलियन लौटाते हैं कि उन्होंने घटना का सेवन किया या नहीं। यह अत्यंत महत्वपूर्ण है यदि आपको एक ही दृश्य के लिए केवल एक हैंडलर की आवश्यकता है (जो कि डिफ़ॉल्ट मामला होना चाहिए, वैसे भी)।
गबोर

क्या है कि टॉगलसोमिंग () विधि?
टंग

1
@ टंग सिर्फ नॉर्मल टैप (जेस्चर नहीं) हैंडलर
ruX

@NicolasZozol जावा कोड शैली, सभी स्वाइप निर्देश, क्लिक हैंडलर पर
ruX

28

Mirek के उत्तर पर विस्तार करना, उस स्थिति के लिए जब आप स्क्रॉल दृश्य के अंदर स्वाइप जेस्चर का उपयोग करना चाहते हैं। डिफ़ॉल्ट रूप से स्क्रॉल श्रोता के लिए टच श्रोता अक्षम हो जाता है और इसलिए स्क्रॉल क्रिया नहीं होती है। इसे ठीक करने के लिए आपको अपने स्वयं के श्रोता के साथ किए जाने के बाद इस पद्धति की dispatchTouchEventविधि को ओवरराइड करना होगा Activityऔर इस पद्धति के विरासत वाले संस्करण को वापस करना होगा।

आदेश Mirek के कोड में कुछ संशोधनों के ऐसा करने के लिए: मैं के लिए एक गेटर जोड़ने gestureDetectorमें OnSwipeTouchListener

public GestureDetector getGestureDetector(){
    return  gestureDetector;
}

OnSwipeTouchListenerगतिविधि को क्लास-वाइड फ़ील्ड के रूप में घोषित करें ।

OnSwipeTouchListener onSwipeTouchListener;

तदनुसार उपयोग कोड को संशोधित करें:

onSwipeTouchListener = new OnSwipeTouchListener(MyActivity.this) {
    public void onSwipeTop() {
        Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeRight() {
        Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeLeft() {
        Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
    }
    public void onSwipeBottom() {
        Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
    }
});

imageView.setOnTouchListener(onSwipeTouchListener);

और dispatchTouchEventअंदर की विधि को ओवरराइड करें Activity:

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

अब स्क्रॉल और स्वाइप एक्शन दोनों को काम करना चाहिए।


यहाँ एक विशाल माइनस - अगर मैं अपने स्क्रोलव्यू पर कहीं भी एक इशारा करता हूँ, तो टचलिस्टर को बुलाया जाता है, भले ही इसे स्क्रोलव्यू पर ही लागू नहीं किया गया हो, लेकिन इसके अंदर एक यादृच्छिक बटन पर
Starwave

23

आदेश रखने के लिए Click Listener, DoubleClick Listener, OnLongPress Listener, Swipe Left, Swipe Right, Swipe Up, Swipe Downएकल पर Viewआप की जरूरत है setOnTouchListener। अर्थात,

view.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) {

            @Override
            public void onClick() {
                super.onClick();
                // your on click here
            }

            @Override
            public void onDoubleClick() {
                super.onDoubleClick();
                // your on onDoubleClick here
            }

            @Override
            public void onLongClick() {
                super.onLongClick();
                // your on onLongClick here
            }

            @Override
            public void onSwipeUp() {
                super.onSwipeUp();
                // your swipe up here
            }

            @Override
            public void onSwipeDown() {
                super.onSwipeDown();
                // your swipe down here.
            }

            @Override
            public void onSwipeLeft() {
                super.onSwipeLeft();
                // your swipe left here.
            }

            @Override
            public void onSwipeRight() {
                super.onSwipeRight();
                // your swipe right here.
            }
        });

}

इसके लिए आपको OnSwipeTouchListenerवह क्लास चाहिए जो इम्प्लीमेंट हो OnTouchListener

public class OnSwipeTouchListener implements View.OnTouchListener {

private GestureDetector gestureDetector;

public OnSwipeTouchListener(Context c) {
    gestureDetector = new GestureDetector(c, new GestureListener());
}

public boolean onTouch(final View view, final MotionEvent motionEvent) {
    return gestureDetector.onTouchEvent(motionEvent);
}

private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

    private static final int SWIPE_THRESHOLD = 100;
    private static final int SWIPE_VELOCITY_THRESHOLD = 100;

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

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

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

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

    // Determines the fling velocity and then fires the appropriate swipe event accordingly
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        boolean result = false;
        try {
            float diffY = e2.getY() - e1.getY();
            float diffX = e2.getX() - e1.getX();
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        onSwipeRight();
                    } else {
                        onSwipeLeft();
                    }
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeDown();
                    } else {
                        onSwipeUp();
                    }
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}

public void onSwipeRight() {
}

public void onSwipeLeft() {
}

public void onSwipeUp() {
}

public void onSwipeDown() {
}

public void onClick() {

}

public void onDoubleClick() {

}

public void onLongClick() {

}
}

2
ज़ाला का समाधान सरल और स्पष्ट है, मुझे एंड्रॉइड में स्वाइप क्रिया के साथ बहुत मदद मिली। यह समाधान उन शुरुआती लोगों को हल करेगा जो स्वाइप इशारों से परेशान हैं।
जेनिफर

2
@ जयदीपसिंह ज़ला, आप मेरा समय बचाते हैं, अद्भुत। यह स्क्रॉल करते समय स्क्रॉल ऊपर और नीचे के सूचक की मेरी समस्या को हल करेगा।
तेजड्रोईड

1
इसे मैं पूर्ण उत्तर कहता हूं। जब मैंने स्वाइप जोड़ा, तो मैंने अपने क्लिक गुण खो दिए, इसलिए मुझे इस उत्तर में ऑनक्लिक विधि को ओवरराइड करने की आवश्यकता थी। धन्यवाद भाई!
जल्द ही सैंटोस

@Jaydipsinh Zala मुझे यकीन नहीं है कि मैं क्या गलत कर रहा हूं, जब मैं अपने वेब व्यू पर OnSwipeTouchListener जोड़ता हूं, तो यह वेबव्यू के अंदर वेबसाइट के साथ बातचीत को हटा देता है। क्या आप मदद कर सकते हैं कृपया?
ALII

11

आपको जटिल गणनाओं की आवश्यकता नहीं है। यह सिर्फ क्लास OnGestureListenerसे इंटरफ़ेस का उपयोग करके किया जा सकता है GestureDetector

अंदर की onFlingविधि से आप इस तरह के चारों दिशाओं का पता लगा सकते हैं:

MyGestureListener.java:

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

public class MyGestureListener implements GestureDetector.OnGestureListener{

    private static final long VELOCITY_THRESHOLD = 3000;

    @Override
    public boolean onDown(final MotionEvent e){ return false; }

    @Override
    public void onShowPress(final MotionEvent e){ }

    @Override
    public boolean onSingleTapUp(final MotionEvent e){ return false; }

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

    @Override
    public void onLongPress(final MotionEvent e){ }

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

        if(Math.abs(velocityX) < VELOCITY_THRESHOLD 
                    && Math.abs(velocityY) < VELOCITY_THRESHOLD){
            return false;//if the fling is not fast enough then it's just like drag
        }

        //if velocity in X direction is higher than velocity in Y direction,
        //then the fling is horizontal, else->vertical
        if(Math.abs(velocityX) > Math.abs(velocityY)){
            if(velocityX >= 0){
                Log.i("TAG", "swipe right");
            }else{//if velocityX is negative, then it's towards left
                Log.i("TAG", "swipe left");
            }
        }else{
            if(velocityY >= 0){
                Log.i("TAG", "swipe down");
            }else{
                Log.i("TAG", "swipe up");
            }
        }

        return true;
    }
}

उपयोग:

GestureDetector mDetector = new GestureDetector(MainActivity.this, new MyGestureListener());

view.setOnTouchListener(new View.OnTouchListener(){
    @Override
    public boolean onTouch(final View v, final MotionEvent event){
        return mDetector.onTouchEvent(event);
    }
});

यहाँ सभी कचरे के माध्यम से बहाया, आप सही हैं, अधिक जटिल चीजों की कोई ज़रूरत नहीं है - यह पूरी तरह से काम करता है
Starwave

क्या VELOCITY_THRESHOLD स्क्रीन घनत्व पर निर्भर नहीं होना चाहिए?
गेरिट बेउज़े

@GerritBeuze नहीं, Android सिस्टम हैंडल करता है। यह विधि के माध्यम से velocityXऔर विधि velocityYमें सही मान भेजता है onFling। यद्यपि आप यह देखने के लिए प्रयोग कर सकते हैं कि आपकी आवश्यकताओं में से कौन सा मूल्य सबसे उपयुक्त है लेकिन अंतिम संख्या सार्वभौमिक होगी।
एमडीपी

यहाँ उत्तर विपरीत मानते हैं: वे तराशे हुए नहीं हैं? : stackoverflow.com/questions/18812479/…
गेरिट बेजू

@GerritBeuze यह इसलिए है क्योंकि वे स्वयं मैन्युअल रूप से गणित कर रहे हैं कि पिक्सल ने कितनी यात्रा की है और उंगली गलत है क्योंकि यह पिक्सेल घनत्व पर निर्भर करता है। आपको केवल वेग का उपयोग करना चाहिए जैसे मैंने किया था, वेग लगभग डीपीआई स्वतंत्र है।
एमडीपी


10

@ मिरेक रुसिन का कोटलिन संस्करण यहां है:

OnSwipeTouchListener.kt:

open class OnSwipeTouchListener(ctx: Context) : OnTouchListener {

    private val gestureDetector: GestureDetector

    companion object {

        private val SWIPE_THRESHOLD = 100
        private val SWIPE_VELOCITY_THRESHOLD = 100
    }

    init {
        gestureDetector = GestureDetector(ctx, GestureListener())
    }

    override fun onTouch(v: View, event: MotionEvent): Boolean {
        return gestureDetector.onTouchEvent(event)
    }

    private inner class GestureListener : SimpleOnGestureListener() {


        override fun onDown(e: MotionEvent): Boolean {
            return true
        }

        override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
            var result = false
            try {
                val diffY = e2.y - e1.y
                val diffX = e2.x - e1.x
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight()
                        } else {
                            onSwipeLeft()
                        }
                        result = true
                    }
                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom()
                    } else {
                        onSwipeTop()
                    }
                    result = true
                }
            } catch (exception: Exception) {
                exception.printStackTrace()
            }

            return result
        }


    }

    open fun onSwipeRight() {}

    open fun onSwipeLeft() {}

    open fun onSwipeTop() {}

    open fun onSwipeBottom() {}
}

उपयोग:

view.setOnTouchListener(object : OnSwipeTouchListener(context) {

    override fun onSwipeTop() {
        super.onSwipeTop()
    }

    override fun onSwipeBottom() {
        super.onSwipeBottom()
    }

    override fun onSwipeLeft() {
        super.onSwipeLeft()
    }

    override fun onSwipeRight() {
        super.onSwipeRight()
    }
})

openकीवर्ड मेरे लिए बिंदु था ...


9

एक onClick जोड़ने के लिए, यहाँ मैंने क्या किया।

....
// in OnSwipeTouchListener class

private final class GestureListener extends SimpleOnGestureListener {

    .... // normal GestureListener  code

   @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        onClick(); // my method
        return super.onSingleTapConfirmed(e);
    }

} // end GestureListener class

    public void onSwipeRight() {
    }

    public void onSwipeLeft() {
    }

    public void onSwipeTop() {
    }

    public void onSwipeBottom() {
    }

    public void onClick(){ 
    }


    // as normal
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
}

} // end OnSwipeTouchListener class

मैं Fragments का उपयोग कर रहा हूं, इसलिए संदर्भ के लिए getActivity () का उपयोग कर रहा हूं। यह मैंने इसे कैसे लागू किया - और यह काम करता है।


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

            public void onClick(){
                Toast.makeText(getActivity(), "clicked", Toast.LENGTH_SHORT).show();
            }
        });

5

@ एडवर्ड ब्रे का तरीका बहुत अच्छा काम करता है। यदि कोई इसके लिए आयातों को कॉपी और पेस्ट करना चाहेगा OnSwipeTouchListener, तो वे यहां हैं:

 import android.content.Context;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnTouchListener;

3

@ मिरेक रुसिन जवाब का थोड़ा संशोधन और अब आप मल्टीटच स्वाइप का पता लगा सकते हैं। यह कोड कोटलिन पर है:

class OnSwipeTouchListener(ctx: Context, val onGesture: (gestureCode: Int) -> Unit) : OnTouchListener {

private val SWIPE_THRESHOLD = 200
private val SWIPE_VELOCITY_THRESHOLD = 200

private val gestureDetector: GestureDetector

var fingersCount = 0

fun resetFingers() {
    fingersCount = 0
}

init {
    gestureDetector = GestureDetector(ctx, GestureListener())
}

override fun onTouch(v: View, event: MotionEvent): Boolean {
    if (event.pointerCount > fingersCount) {
        fingersCount = event.pointerCount
    }
    return gestureDetector.onTouchEvent(event)
}

private inner class GestureListener : SimpleOnGestureListener() {

    override fun onDown(e: MotionEvent): Boolean {
        return true
    }

    override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
        var result = false
        try {
            val diffY = e2.y - e1.y
            val diffX = e2.x - e1.x
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        val gesture = when (fingersCount) {
                            1 -> Gesture.SWIPE_RIGHT
                            2 -> Gesture.TWO_FINGER_SWIPE_RIGHT
                            3 -> Gesture.THREE_FINGER_SWIPE_RIGHT
                            else -> -1
                        }
                        if (gesture > 0) {
                            onGesture.invoke(gesture)
                        }
                    } else {
                        val gesture = when (fingersCount) {
                            1 -> Gesture.SWIPE_LEFT
                            2 -> Gesture.TWO_FINGER_SWIPE_LEFT
                            3 -> Gesture.THREE_FINGER_SWIPE_LEFT
                            else -> -1
                        }
                        if (gesture > 0) {
                            onGesture.invoke(gesture)
                        }
                    }
                    resetFingers()
                }
            } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                if (diffY > 0) {
                    val gesture = when (fingersCount) {
                        1 ->  Gesture.SWIPE_DOWN
                        2 -> Gesture.TWO_FINGER_SWIPE_DOWN
                        3 -> Gesture.THREE_FINGER_SWIPE_DOWN
                        else -> -1
                    }
                    if (gesture > 0) {
                        onGesture.invoke(gesture)
                    }
                } else {
                    val gesture = when (fingersCount) {
                        1 ->  Gesture.SWIPE_UP
                        2 -> Gesture.TWO_FINGER_SWIPE_UP
                        3 -> Gesture.THREE_FINGER_SWIPE_UP
                        else -> -1
                    }
                    if (gesture > 0) {
                        onGesture.invoke(gesture)
                    }
                }
                resetFingers()
            }
            result = true

        } catch (exception: Exception) {
            exception.printStackTrace()
        }

        return result
    }
}}

जहां Gesture.SWIPE_RIGHT और अन्य लोग इशारे के अनूठे पूर्णांक सूचक हैं, जिन्हें मैं अपनी गतिविधि में बाद में हावभाव का पता लगाने के लिए उपयोग कर रहा हूं:

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

तो आप देखते हैं कि इशारे यहाँ एक पूर्णांक चर है जो मूल्य रखता है जो मैंने पहले पारित किया है।


क्या कोई कृपया मुझे उदाहरण के तौर पर दिखा सकता है कि कोटलिन का उपयोग करने के लिए बाएं स्वाइप और एक ही दृश्य पर सामान्य क्लिक दोनों का पता कैसे लगाया जा सकता है।
उपयोगकर्ता 3561494

आप इसे सूची दृश्य में कैसे उपयोग करते हैं? यह उस दृश्य की स्थिति को वापस नहीं करता है जिसे स्पर्श किया गया था, तो आप कैसे जानते हैं कि किस पंक्ति को स्पर्श किया गया था?
उपयोगकर्ता 3561494 22

इशारे क्या आयात से आता है? आयात android.gesture.Gesture में SWIPE_RIGHT वैश्विक नहीं है।
JPM

आपने इस इशारे का पूरा कोड क्यों नहीं लिखा, जहां स्वाइपडाउन, बाएं, दाएं आदि को रखा जाए?
बेनामी-ई

3

मेरा समाधान उपरोक्त लोगों के समान है, लेकिन मैंने जेस्चर हैंडलिंग को एक अमूर्त वर्ग में बदल दिया है OnGestureRegisterListener.java, जिसमें स्वाइप , क्लिक और लॉन्ग क्लिक जेस्चर शामिल हैं।

OnGestureRegisterListener.java

public abstract class OnGestureRegisterListener implements View.OnTouchListener {

    private final GestureDetector gestureDetector;
    private View view;

    public OnGestureRegisterListener(Context context) {
        gestureDetector = new GestureDetector(context, new GestureListener());
    }

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        this.view = view;
        return gestureDetector.onTouchEvent(event);
    }

    public abstract void onSwipeRight(View view);
    public abstract void onSwipeLeft(View view);
    public abstract void onSwipeBottom(View view);
    public abstract void onSwipeTop(View view);
    public abstract void onClick(View view);
    public abstract boolean onLongClick(View view);

    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

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

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

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

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            onSwipeRight(view);
                        } else {
                            onSwipeLeft(view);
                        }
                        result = true;
                    }
                }
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        onSwipeBottom(view);
                    } else {
                        onSwipeTop(view);
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }

    }
}

और इसका इस्तेमाल ऐसे करें। ध्यान दें कि आप आसानी से अपने Viewपैरामीटर में पास कर सकते हैं ।

OnGestureRegisterListener onGestureRegisterListener = new OnGestureRegisterListener(this) {
    public void onSwipeRight(View view) {
        // Do something
    }
    public void onSwipeLeft(View view) {
        // Do something
    }
    public void onSwipeBottom(View view) {
        // Do something
    }
    public void onSwipeTop(View view) {
        // Do something
    }
    public void onClick(View view) {
        // Do something
    }
    public boolean onLongClick(View view) { 
        // Do something
        return true;
    }
};

Button button = findViewById(R.id.my_button);
button.setOnTouchListener(onGestureRegisterListener);

3

मैं इसी तरह की चीजें कर रहा हूं, लेकिन केवल क्षैतिज स्वाइप के लिए

import android.content.Context
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View

abstract class OnHorizontalSwipeListener(val context: Context) : View.OnTouchListener {    

    companion object {
         const val SWIPE_MIN = 50
         const val SWIPE_VELOCITY_MIN = 100
    }

    private val detector = GestureDetector(context, GestureListener())

    override fun onTouch(view: View, event: MotionEvent) = detector.onTouchEvent(event)    

    abstract fun onRightSwipe()

    abstract fun onLeftSwipe()

    private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {    

        override fun onDown(e: MotionEvent) = true

        override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float)
            : Boolean {

            val deltaY = e2.y - e1.y
            val deltaX = e2.x - e1.x

            if (Math.abs(deltaX) < Math.abs(deltaY)) return false

            if (Math.abs(deltaX) < SWIPE_MIN
                    && Math.abs(velocityX) < SWIPE_VELOCITY_MIN) return false

            if (deltaX > 0) onRightSwipe() else onLeftSwipe()

            return true
        }
    }
}

और फिर इसका उपयोग दृश्य घटकों के लिए किया जा सकता है

private fun listenHorizontalSwipe(view: View) {
    view.setOnTouchListener(object : OnHorizontalSwipeListener(context!!) {
            override fun onRightSwipe() {
                Log.d(TAG, "Swipe right")
            }

            override fun onLeftSwipe() {
                Log.d(TAG, "Swipe left")
            }

        }
    )
}

3

यह सवाल कई साल पहले पूछा गया था। अब, एक बेहतर उपाय है: SmartSwipe: https://github.com/luckybilly/SmartSwipe

कोड इस तरह दिखता है:

SmartSwipe.wrap(contentView)
        .addConsumer(new StayConsumer()) //contentView stay while swiping with StayConsumer
        .enableAllDirections() //enable directions as needed
        .addListener(new SimpleSwipeListener() {
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                //direction: 
                //  1: left
                //  2: right
                //  4: top
                //  8: bottom
            }
        })
;

विभिन्न साइडलिप प्रभावों के लिए कई SwipeConsumers हैं, जैसे कि SlidingConsumer / StretchConsumer / SpaceConsumer / ... और इतने पर SmartSwipe
luckybilly

1

@ मिरेक रुसिन अन्सवेइर बहुत अच्छा है। लेकिन, छोटा सा बग है, और ठीक किया गया है -

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            if (getOnSwipeListener() != null) {
                                getOnSwipeListener().onSwipeRight();
                            }
                        } else {
                            if (getOnSwipeListener() != null) {
                                getOnSwipeListener().onSwipeLeft();
                            }
                        }
                        result = true;
                    }
                }
                else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        if (getOnSwipeListener() != null) {
                            getOnSwipeListener().onSwipeBottom();
                        }
                    } else {
                        if (getOnSwipeListener() != null) {
                            getOnSwipeListener().onSwipeTop();
                        }
                    }
                    result = true;
                }

क्या अंतर है? हम परिणाम = सही सेट करते हैं, केवल अगर हमने जाँच की है कि सभी requrinments (दोनों SWIPE_THRESHOLD और SWIPE_VELOCITY_THRESHOLD ठीक हैं)। यह महत्वपूर्ण है अगर हम स्वाइप को त्याग देते हैं यदि कुछ पुनर्खरीद हासिल नहीं की जाती है, और हमें ऑनस्विच विधि का उपयोग करना होगा।


1

इशारे की दिशा का पता लगाने के लिए यहां सरल एंड्रॉइड कोड है

में MainActivity.javaऔर activity_main.xml, लिखने के लिए निम्न कोड:

MainActivity.java

import java.util.ArrayList;

import android.app.Activity;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.GestureStroke;
import android.gesture.Prediction;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends Activity implements
        OnGesturePerformedListener {

    GestureOverlayView gesture;
    GestureLibrary lib;
    ArrayList<Prediction> prediction;

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

        lib = GestureLibraries.fromRawResource(MainActivity.this,
                R.id.gestureOverlayView1);
        gesture = (GestureOverlayView) findViewById(R.id.gestureOverlayView1);
        gesture.addOnGesturePerformedListener(this);
    }

    @Override
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
        ArrayList<GestureStroke> strokeList = gesture.getStrokes();
        // prediction = lib.recognize(gesture);
        float f[] = strokeList.get(0).points;
        String str = "";

        if (f[0] < f[f.length - 2]) {
            str = "Right gesture";
        } else if (f[0] > f[f.length - 2]) {
            str = "Left gesture";
        } else {
            str = "no direction";
        }
        Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();

    }

}

activity_main.xml

<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android1="http://schemas.android.com/apk/res/android"
    xmlns:android2="http://schemas.android.com/apk/res/android"
    android:id="@+id/gestureOverlayView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android1:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Draw gesture"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</android.gesture.GestureOverlayView>

1
import android.content.Context
import android.view.GestureDetector
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener

/**
 * Detects left and right swipes across a view.
 */
class OnSwipeTouchListener(context: Context, onSwipeCallBack: OnSwipeCallBack?) : OnTouchListener {

    private var gestureDetector : GestureDetector
    private var onSwipeCallBack: OnSwipeCallBack?=null

    init {

        gestureDetector = GestureDetector(context, GestureListener())
        this.onSwipeCallBack = onSwipeCallBack!!
    }
    companion object {

        private val SWIPE_DISTANCE_THRESHOLD = 100
        private val SWIPE_VELOCITY_THRESHOLD = 100
    }

   /* fun onSwipeLeft() {}

    fun onSwipeRight() {}*/

    override fun onTouch(v: View, event: MotionEvent): Boolean {


        return gestureDetector.onTouchEvent(event)
    }

    private inner class GestureListener : SimpleOnGestureListener() {

        override fun onDown(e: MotionEvent): Boolean {
            return true
        }

        override fun onFling(eve1: MotionEvent?, eve2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
            try {
                if(eve1 != null&& eve2!= null) {
                    val distanceX = eve2?.x - eve1?.x
                    val distanceY = eve2?.y - eve1?.y
                    if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (distanceX > 0)
                            onSwipeCallBack!!.onSwipeLeftCallback()
                        else
                            onSwipeCallBack!!.onSwipeRightCallback()
                        return true
                    }
                }
            }catch (exception:Exception){
                exception.printStackTrace()
            }

            return false
        }


    }
}

कोटलिन के लिए आप कुछ इस तरह का उपयोग कर सकते हैं:
कमल

उपयोग: gv_calendar !! !! setOnTouchListener (OnSwipeTouchListener (गतिविधि, onSwipeCallBack !!))
kamal

5
कृपया कोड को डंप न करें, आपके कोड में क्या है इसका स्पष्टीकरण शामिल करें।
मार्क रोटिटेवेल

OnSwipeCallBack क्या है?
तस्किन

0

यदि आप किसी सूची आइटम के स्वाइप होने पर क्रियाओं के साथ कुछ बटन प्रदर्शित करना चाहते हैं, तो इंटरनेट पर बहुत सारे पुस्तकालय हैं जिनमें यह व्यवहार है। मैंने लाइब्रेरी को लागू किया जो मुझे इंटरनेट पर मिली और मैं बहुत संतुष्ट हूं। यह उपयोग करने के लिए बहुत सरल है और बहुत जल्दी है। मैंने मूल पुस्तकालय में सुधार किया और मैंने आइटम क्लिक के लिए एक नया क्लिक श्रोता जोड़ा। इसके अलावा मैंने फ़ॉन्ट भयानक पुस्तकालय ( http://fortawesome.github.io/Font-Awesome/ जोड़ा ) और अब आप बस एक नया आइटम शीर्षक जोड़ सकते हैं और फ़ॉन्ट भयानक से आइकन का नाम निर्दिष्ट कर सकते हैं।

यहाँ github लिंक दिया गया है


0
public class TranslatorSwipeTouch implements OnTouchListener
{
   private String TAG="TranslatorSwipeTouch";

   @SuppressWarnings("deprecation")
   private GestureDetector detector=new GestureDetector(new TranslatorGestureListener());

   @Override
   public boolean onTouch(View view, MotionEvent event)
   {
     return detector.onTouchEvent(event);
   }

private class TranslatorGestureListener extends SimpleOnGestureListener 
{
    private final int GESTURE_THRESHOULD=100;
    private final int GESTURE_VELOCITY_THRESHOULD=100;

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

    @Override
    public boolean onFling(MotionEvent event1,MotionEvent event2,float velocityx,float velocityy)
    {
        try
        {
            float diffx=event2.getX()-event1.getX();
            float diffy=event2.getY()-event1.getY();

            if(Math.abs(diffx)>Math.abs(diffy))
            {
                if(Math.abs(diffx)>GESTURE_THRESHOULD && Math.abs(velocityx)>GESTURE_VELOCITY_THRESHOULD)
                {
                    if(diffx>0)
                    {
                        onSwipeRight();
                    }
                    else
                    {
                        onSwipeLeft();
                    }
                }
            }
            else
            {
                if(Math.abs(diffy)>GESTURE_THRESHOULD && Math.abs(velocityy)>GESTURE_VELOCITY_THRESHOULD)
                {
                    if(diffy>0)
                    {
                         onSwipeBottom();
                    }
                    else
                    {
                        onSwipeTop();
                    }
                }
            }
        }
        catch(Exception e)
        {
            Log.d(TAG, ""+e.getMessage());
        }
        return false;           
    }

    public void onSwipeRight()
    {
        //Toast.makeText(this.getClass().get, "swipe right", Toast.LENGTH_SHORT).show();
        Log.i(TAG, "Right");
    }
    public void onSwipeLeft()
    {
        Log.i(TAG, "Left");
        //Toast.makeText(MyActivity.this, "swipe left", Toast.LENGTH_SHORT).show();
    }

    public void onSwipeTop()
    {
        Log.i(TAG, "Top");
        //Toast.makeText(MyActivity.this, "swipe top", Toast.LENGTH_SHORT).show();
    }

    public void onSwipeBottom()
    {
        Log.i(TAG, "Bottom");
        //Toast.makeText(MyActivity.this, "swipe bottom", Toast.LENGTH_SHORT).show();
    }   

  }

 }

2
कोड का बड़ा हिस्सा वास्तव में पाठकों को मूल्य देने के लिए स्पष्टीकरण की आवश्यकता है। विशेष रूप से कोड जो कि डिप्रेशन चेतावनियों को दबा देता है। आपको वास्तव में यह समझाने की आवश्यकता है कि ऐसे मामले में यह कोड क्यों आवश्यक है।
स्टीफन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.