2012-09-13 10 views
7

मुझे पता है कि डबल-क्लिक और दो-उंगली स्पर्श ईवेंट का पता कैसे लगाया जाए, लेकिन मैं इन्हें प्रतिक्रिया देने के लिए कैसे जोड़ सकता हूं ताकि किसी को दो अंगुलियों से डबल क्लिक करने की आवश्यकता हो?एंड्रॉइड में दो-उंगली डबल-क्लिक को कैसे कार्यान्वित करें?

डिफ़ॉल्ट रूप से, एंड्रॉइड के पास क्लिक करने के दूसरे रूप के रूप में कार्य करने के लिए लंबी प्रेस होती है, लेकिन मैं विशेष रूप से दो-उंगली डबल-क्लिक की तलाश में हूं।

उत्तर

14

मैं एक साधारण चाहता था और पुन: प्रयोज्य इंटरफेस जो दो उंगली डबल नल और व्यवहार के लिए सुनता है GestureDetector की तरह aves।

public class Example extends Activity { 
    SimpleTwoFingerDoubleTapDetector multiTouchListener = new SimpleTwoFingerDoubleTapDetector() { 
     @Override 
     public void onTwoFingerDoubleTap() { 
      // Do what you want here, I used a Toast for demonstration 
      Toast.makeText(Example.this, "Two Finger Double Tap", Toast.LENGTH_SHORT).show(); 
     } 
    }; 

    // Override onCreate() and anything else you want 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if(multiTouchListener.onTouchEvent(event)) 
      return true; 
     return super.onTouchEvent(event); 
    } 
} 

मैं SimpleTwoFingerDoubleTapDetector बनाया: आप इस तरह इसका इस्तेमाल कर सकते हैं, जिससे कि (सभी & पेस्ट runnable कोड कटा हुआ)। (यह एक लंबे नाम है, लेकिन यह वर्णनात्मक है आप जो भी चाहें के रूप में यह नाम बदल सकते हैं।।) अपनी परियोजना के अंदर या एक पुस्तकालय के रूप में इस नई फ़ाइल सहेजें (

public abstract class SimpleTwoFingerDoubleTapDetector { 
    private static final int TIMEOUT = ViewConfiguration.getDoubleTapTimeout() + 100; 
    private long mFirstDownTime = 0; 
    private boolean mSeparateTouches = false; 
    private byte mTwoFingerTapCount = 0; 

    private void reset(long time) { 
     mFirstDownTime = time; 
     mSeparateTouches = false; 
     mTwoFingerTapCount = 0; 
    } 

    public boolean onTouchEvent(MotionEvent event) { 
     switch(event.getActionMasked()) { 
     case MotionEvent.ACTION_DOWN: 
      if(mFirstDownTime == 0 || event.getEventTime() - mFirstDownTime > TIMEOUT) 
       reset(event.getDownTime()); 
      break; 
     case MotionEvent.ACTION_POINTER_UP: 
      if(event.getPointerCount() == 2) 
       mTwoFingerTapCount++; 
      else 
       mFirstDownTime = 0; 
      break; 
     case MotionEvent.ACTION_UP: 
      if(!mSeparateTouches) 
       mSeparateTouches = true; 
      else if(mTwoFingerTapCount == 2 && event.getEventTime() - mFirstDownTime < TIMEOUT) { 
       onTwoFingerDoubleTap(); 
       mFirstDownTime = 0; 
       return true; 
      } 
     }    

     return false; 
    } 

    public abstract void onTwoFingerDoubleTap(); 
} 

सबसे पहले, एक Android के बारे में कुछ नोट एक- स्पर्श) GestureDetector:

  • Android के onDoubleTap() घटना ViewConfiguration से एक मानक टाइमआउट मान का उपयोग करता है। मैं एक ही समय का संदर्भ देता हूं।
  • वे पहली टैप की उंगली-डाउन घटना से दूसरे टैप की उंगली-डाउन ईवेंट में विलुप्त समय को मापते हैं, और फिर onDoubleTap() और onDoubleTapEvent() प्रसारित करते हैं।
    • onDoubleTap() केवल तभी निकाल दिया जाता है जब दूसरी टैप की उंगली-डाउन घटना होती है।
    • onDoubleTapEvent() दूसरी टैप द्वारा प्रत्येक क्रिया के लिए निकाल दिया गया है: नीचे, स्थानांतरित करें और ऊपर।

पर कुछ नोट SimpleTwoFingerDoubleTapDetector:

  • मेरे टाइमआउट झूठी दो बार स्पर्श करें सूचनाओं को रोकने के लिए घटना पिछले उंगली करने के लिए पहली उंगली से नीचे घटना से मापा जाता है । मैंने इसके लिए खाते में डिफ़ॉल्ट व्यू कॉन्फ़िगरेशन डबल टैप टाइमआउट में थोड़ा अतिरिक्त समय जोड़ा।
  • एंड्रॉइड के जेस्चर डिटेक्टर उपाय ढलान (दो नल कितनी दूर हैं)। मैंने यहां इसकी आवश्यकता नहीं देखी, न ही मैंने प्रत्येक टैप पर दो अंगुलियों के बीच की दूरी की जांच की।
  • मैंने केवल एक ईवेंट onTwoFingerDoubleTap() प्रसारित किया।

अंतिम नोट:

  1. SimpleTwoFingerDoubleTapDetector के बदले परिभाषा:

    public abstract class SimpleTwoFingerDoubleTapListener implements OnTouchListener { 
    
  2. एक जोड़े आप आसानी से परिवर्तन यह एक OnTouchListener की तरह व्यवहार करने के लिए कर सकते हैं नया वर्ग चर:

    private View mFirstView; 
    
  3. बदलें ACTION_DOWN मामला:

    case MotionEvent.ACTION_DOWN: 
        if(mFirstDownTime == -1 || mFirstView != v || hasTimedOut(event.getEventTime())) { 
         mFirstView = v; 
         reset(event.getDownTime()); 
        } 
        break; 
    
  4. पास mFirstViewACTION_UP मामले के अंदर:

    onTwoFingerDoubleTap(mFirstView); 
    
  5. अंतिम है, जो दृश्य को प्रतिबिंबित करने के onTwoFingerDoubleTap() पद्धति को बदलने टैप किया गया था:

    public abstract void onTwoFingerDoubleTap(View v); 
    
+0

यह उत्तर कमाल है! – dowi

+2

मैंने इस कोड को आजमाया है (धन्यवाद!) और यह काम नहीं किया - मुझे केवल ACTION_DOWN घटनाएं मिल रही थीं। मेरा मानना ​​है कि onTouchEvent() फ़ंक्शन को सत्य (ACTION_DOWN के लिए) वापस करना होगा या अन्यथा ACTION_UP बाद में प्राप्त नहीं होगा। इसका संदर्भ लें: http://stackoverflow.com/a/16495363/1277048 – FuzzyAmi

1

यह दो-उंगली डबल क्लिक का पता लगाने के लिए बनाया गया एक डबल-क्लिक श्रोता है।

चर का प्रयोग किया:

private GestureDetector gesture; 
private View.OnTouchListener gestureListener; 
boolean click1 = false; 
boolean click2 = false; 
long first = 0; 
long second = 0; 

गतिविधि के onCreate() रजिस्टर करने के लिए स्पर्श इवेंट में:

gesture = new GestureDetector(getApplicationContext(), new SimpleOnGestureListener(){ 
    public boolean onDown(MotionEvent event) { 
     return true; 
    } 
}); 
gestureListener = new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     return gesture.onTouchEvent(event); 
    } 
}; 

onCreate() गतिविधि के अंदर के बाहर:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    try { 
     int action = event.getAction() & MotionEvent.ACTION_MASK; 
     //capture the event when the user lifts their fingers, not on the down press 
     //to make sure they're not long pressing 
     if (action == MotionEvent.ACTION_POINTER_UP) { 
      //timer to get difference between clicks 
      Calendar now = Calendar.getInstance(); 

      //detect number of fingers, change to 1 for a single-finger double-click, 3 for a triple-finger double-click, etc. 
      if (event.getPointerCount() == 2) { 
       if (!click1) { 
        //if this is the first click, then there hasn't been a second 
        //click yet, also record the time 
        click1 = true; 
        click2 = false; 
        first = now.getTimeInMillis(); 
       } else if (click1) { 
        //if this is the second click, record its time 
        click2 = true; 
        second = now.getTimeInMillis(); 

        //if the difference between the 2 clicks is less than 500 ms (1/2 second) 
        //Math.abs() is used because you need to be able to detect any sequence of clicks, rather than just in pairs of two 
        //(e.g. click1 could be registered as a second click if the difference between click1 and click2 > 500 but 
        //click2 and the next click1 is < 500) 
        if (Math.abs(second-first) < 500) { 

         //do something!!!!!! 

        } else if (Math.abs(second-first) >= 500) { 
         //reset to handle more clicks 
         click1 = false; 
         click2 = false; 
        } 
       } 
      } 
     } 
    } catch (Exception e){ 

    } 
    return true; 
} 
+0

केवल पहली बार काम करता है। – Nezam

+0

'if (क्लिक 1 और& click2 && Math.abs (द्वितीय-प्रथम) <500) {...}' ओवरकिल है। आप कोड के इस विशेष भाग तक नहीं पहुंच सकते हैं जब तक कि 'क्लिक 1 और& क्लिक 2' पहले से ही सत्य न हो। यहां पहुंचने के लिए, आपको इसे पार करना होगा: 'अगर (क्लिक 1) {क्लिक 2 = सत्य; ...} '। वही प्रभाव 'if (Math.abs (second-first) <500) के साथ हासिल किया जा सकता है {// कुछ करें !!!!!! } else {click1 = false; क्लिक 2 = झूठी;} ' –

+0

@Nezam मैंने इस कोड का उपयोग अब वर्षों में नहीं किया है, लेकिन मुझे यकीन नहीं है कि यह क्यों होगा - यह हमारे ऐप – WOUNDEDStevenJones

संबंधित मुद्दे