2011-05-31 32 views
15

के साथ प्रतिस्पर्धा करने वाले टचएवेंट पर ओवरराइड करना एक सरल अवलोकन से मेरे पास एक कस्टम व्यू है जिसमें कुछ बिटमैप हैं जो उपयोगकर्ता खींच सकते हैं और आकार बदल सकते हैं।स्क्रॉलव्यू

तरह से मैं यह काफी मानक के रूप में मैं अपने CustomView में onTouchEvent ओवरराइड और देखें कि क्या उपयोगकर्ता एक छवि के भीतर को छू रहा है, आदि

मेरे समस्या आता है जब मैं एक scrollview में इस CustomView रखना चाहते हैं । यह काम करता है, लेकिन स्क्रॉलव्यू और कस्टम व्यू मोशनएवेंट्स के लिए प्रतिस्पर्धा करने लगते हैं, यानी जब मैं किसी छवि को खींचने का प्रयास करता हूं तो यह आलसी या दृश्य स्क्रॉल चलाता है।

मुझे लगता है कि मुझे स्क्रॉलव्यू का विस्तार करना पड़ सकता है, इसलिए मैं इंटरसेप्ट टचवेन्ट पर ओवरराइड कर सकता हूं और यह बता सकता हूं कि उपयोगकर्ता छवि की सीमाओं के भीतर है या नहीं, कोशिश करने और स्क्रॉल करने के लिए। लेकिन फिर स्क्रॉलव्यू पदानुक्रम में अधिक है क्योंकि मैं कस्टमव्यू के वर्तमान स्थिति तक कैसे पहुंच पाऊंगा?

क्या कोई बेहतर तरीका है?

+1

मुझे लगता है कि अपने कस्टम दृश्य onInterceptTouchEvent को लागू करना चाहिए और व्यवस्था तय करने के लिए अगर यह स्पर्श घटना तदनुसार संभाल चाहिए में नहीं scrollview और फिर घटना बंद हाथ अगर यह नहीं करने का फैसला इसे संभालने के लिए। – Nadewad

उत्तर

38

आम तौर पर एंड्रॉइड इन तरह के मामलों में ड्रैग शुरू करने के लिए एक लंबी प्रेस का उपयोग करता है क्योंकि जब उपयोगकर्ता किसी आइटम को खींचने का इरादा रखता है तो आइटम को कंटेनर स्क्रॉल करने में मदद करता है। लेकिन यदि आपके पास कोई आइटम खींचने पर कोई स्पष्ट संकेत है, तो कस्टम दृश्य से getParent().requestDisallowInterceptTouchEvent(true) आज़माएं जब आप जानते हैं कि उपयोगकर्ता ड्रैग शुरू कर रहा है। (इस विधि के लिए डॉक्स here।) यह वर्तमान इशारा के अंत तक स्क्रॉलव्यू को टच इवेंट्स को अवरुद्ध करने से रोक देगा।

+2

आपको बहुत धन्यवाद, यह काम किया! SO पर कुछ महान एपीआई ज्ञान यहां दिए गए हैं :) – brk3

+1

यह आपकी मदद करता है जब आपके पास प्लेटफॉर्म में इन चीजों को बनाए रखने वाले लोग आपके प्रश्नों का उत्तर देते हैं। ;) – adamp

+0

इस के लिए धन्यवाद :) –

8

समाधान मिलने से कोई भी मेरे लिए "बॉक्स से बाहर" में काम किया, शायद इसलिए कि मेरे कस्टम दृश्य फैली देखें, नहीं ViewGroup, और इस तरह मैं onInterceptTouchEvent लागू नहीं कर सकते।

getParent().requestDisallowInterceptTouchEvent(true) को भी कॉल करना एनपीई फेंक रहा था, या कुछ भी नहीं कर रहा था। अपने कस्टम onTouchEvent कॉल requestDisallow... अंदर
जब आपके विचार घटना का ख्याल रखेंगे:

अंत में यह कैसे मैं समस्या हल है। उदाहरण के लिए:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    Point pt = new Point((int)event.getX(), (int)event.getY()); 
    if (event.getAction() == MotionEvent.ACTION_DOWN) { 
     if (/*this is an interesting event my View will handle*/) { 
      // here is the fix! now without NPE 
      if (getParent() != null) { 
       getParent().requestDisallowInterceptTouchEvent(true); 
      } 

      clicked_on_image = true; 
     } 
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
     if (clicked_on_image) { 
      //do stuff, drag the image or whatever 
     } 
    } else if (event.getAction() == MotionEvent.ACTION_UP) { 
     clicked_on_image = false; 
    } 
    return true; 
} 

अब मेरी कस्टम दृश्य ठीक काम करता है, कुछ घटनाओं से निपटने और दे scrollview जिन्हें हम परवाह नहीं करते पकड़ने। यहां समाधान मिला: http://android-devblog.blogspot.com.es/2011/01/scrolling-inside-scrollview.html

उम्मीद है कि यह मदद करता है।

+0

बहुत बढ़िया उत्तर नहीं मिला, तो मैंने उम्र के लिए यह खोज लिया होगा, इससे मदद मिली! :) लेकिन मैं नल पॉइंटर चेक को बदलने का सुझाव देता हूं: व्यूअरेंट पैरेंट = getParent(); अगर (पैरेंट! = शून्य) { parent.requestDisallowInterceptTouchEvent (सत्य); } – netzpurist

+0

धन्यवाद यह पूरी तरह से काम किया – Ryan

0

एक एंड्रॉइड ईवेंट है जिसे मोशनइवेंट.एक्शन_CANCEL (value = 3) कहा जाता है। मैं बस अपने कस्टम नियंत्रण के टचवेन्ट विधि को ओवरराइड करता हूं और इस मान को कैप्चर करता हूं। अगर मैं इस स्थिति का पता लगाता हूं तो मैं तदनुसार जवाब देता हूं।

यहाँ कुछ कोड है:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if(isTouchable) { 
     int maskedAction = event.getActionMasked();   
     if (maskedAction == MotionEvent.ACTION_DOWN) { 
      this.setTextColor(resources.getColor(R.color.octane_orange)); 
      initialClick = event.getX(); 
     } else if (maskedAction == MotionEvent.ACTION_UP) { 
      this.setTextColor(defaultTextColor); 
      endingClick = event.getX(); 
      checkIfSwipeOrClick(initialClick, endingClick, range); 
     } else if(maskedAction == MotionEvent.ACTION_CANCEL) 
      this.setTextColor(defaultTextColor); 
    } 
    return true; 
} 
संबंधित मुद्दे