2012-09-25 34 views
18

का उपयोग करके राज्यों (कस्टम एक्सएमएल चयनकर्ता) को बदलने की जरूरत है। मुझे एक बटन ग्राफ़िक मिला है जिसे "प्रेस और होल्ड" कार्यक्षमता की आवश्यकता है, इसलिए ऑनक्लिक लिस्टनर का उपयोग करने के बजाय, मैं उपयोग कर रहा हूं onTouchListener ताकि एप्लिकेशनएंड्रॉइड पर "प्रेस एंड होल्ड" बटन को टचलिस्टर

MotionEvent.ACTION_DOWN, 

और

MotionEvent.ACTION_UP 

पर प्रतिक्रिया कर सकते हैं कि कैसे जल्दी से उन दो ईवेंट ट्रिगर कर रहे हैं पर निर्भर करता है, मैं दोनों के बीच के समय में एक "pressAndHoldHandler" चला सकते हैं।

वैसे भी, लंबी कहानी छोटी: मेरे पास एक ही ऐप में कई "मूल" बटन हैं जिन्हें प्रेस और पकड़ कार्यक्षमता की आवश्यकता नहीं है, इसलिए वे ऑनक्लिक लिस्टनर का उपयोग कर रहे हैं।

हर इन बटनों में से एक एक अपने स्वयं के एक्सएमएल चयनकर्ता फ़ाइल के साथ रेखांकन अनुकूलित किया गया है:

<?xml version="1.0" encoding="UTF-8"?> 
<selector 
    xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item 
     android:state_enabled="false" 
     android:drawable="@drawable/btn_chicken_off" /> 

    <item 
     android:state_enabled="true" 
     android:state_pressed="true" 
     android:drawable="@drawable/btn_chicken_s3" /> 

    <item 
     android:state_enabled="true" 
     android:state_focused="true" 
     android:drawable="@drawable/btn_chicken_s2" /> 

    <item 
     android:state_enabled="true" 
     android:drawable="@drawable/btn_chicken_off" /> 

</selector> 

तो, समस्या यहाँ है: ऊपर चयनकर्ता onTouchListener के साथ पहुँचा नहीं होती है। केवल ऑनक्लिक लिस्टनर राज्य की परिवर्तनों को अपने स्वयं के विधि के ऑनक्लिक() सेक्शन में खींच देगा, इसलिए ये "प्रेस और होल्ड" बटन कभी भी राज्य को नहीं बदलते हैं। उपयोगकर्ता के लिए बहुत भयानक प्रतिक्रिया।

मैं वर्तमान में निम्न कार्य करके ACTION_DOWN के स्विच मामले और ACTION_UP अंदर से ऊपर के लिए मजबूर कर रहा हूँ:

if (action == MotionEvent.ACTION_DOWN) { 
    btn_chicken.setBackgroundResource(R.drawable.btn_chicken_s3); 
} 
else 
    if (action == MotionEvent.ACTION_UP) { 
     btn_chicken.setBackgroundResource(R.drawable.btn_chicken_off); 
    } 

लेकिन यह एक हैक की तरह लगता है, और यह "ध्यान केंद्रित लेकिन नहीं दबाया" मंच कमी है।

कोई भी इस से पहले घूम गया?

+0

यही मेरी समस्या थी। अच्छे विवरण के लिए धन्यवाद। – Suragch

उत्तर

41

दबाए गए व्यवहार को अनुकरण करने के लिए view.setPressed() फ़ंक्शन का उपयोग करें।

आप शायद जब आप ACTION_DOWN घटना प्राप्त दबाया राज्य सक्षम है और जब आप ACTION_UP घटना मिलता है इसे अक्षम करना चाहते हैं।

साथ ही, यदि उपयोगकर्ता बटन से बाहर निकलता है तो इसे अक्षम करना एक अच्छा विचार होगा।, ACTION_OUTSIDE घटना पकड़ने के रूप में नीचे दिखाए गए उदाहरण:

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

    switch (event.getAction() & MotionEvent.ACTION_MASK) { 

    case MotionEvent.ACTION_DOWN: 
     v.setPressed(true); 
     // Start action ... 
     break; 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_OUTSIDE: 
    case MotionEvent.ACTION_CANCEL: 
     v.setPressed(false); 
     // Stop action ... 
     break; 
    case MotionEvent.ACTION_POINTER_DOWN: 
     break; 
    case MotionEvent.ACTION_POINTER_UP: 
     break; 
    case MotionEvent.ACTION_MOVE: 
     break; 
    } 

    return true; 
} 
+2

मुझे नहीं लगता कि ACTION_OUTSIDE वास्तव में ट्रिगर हो जाता है। यह विशेष रूप से संवाद के बाहर छूने के लिए प्रतीत होता है। – yincrash

+0

'ACTION_CANCEL'' view.setPressed (false) को कॉल करने के लिए एक अच्छी जगह होगी; ' –

+0

' motionEvent.ACTION_UP में 'view.setPressed (false)' डालकर: 'मेरे लिए काम किया। मैं इसे काम नहीं कर सका, भले ही मैं सिर्फ अपना उठाने के बजाय दृश्य से दूर हो गया उंगली। – Suragch

2

आप बस क्लिक करेंक्लिक लिस्टनर पर बटन सेट कर सकते हैं और इसकी ऑनक्लिक विधि खाली छोड़ सकते हैं। आपका तर्क टच के अंदर लागू होता है। इस तरह आपके पास प्रेस प्रभाव होगा।

पी.एस आप आप बस का उपयोग कर सकते चयनकर्ता में उन सभी राज्य की जरूरत नहीं है:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" > 

    <item android:state_pressed="true" android:drawable="@drawable/IMAGE_PRESSED" /> 

    <item android:drawable="@drawable/IMAGE" /> 

</selector> 
+0

अच्छी तरह से, मैंने कोशिश की, और यह काम नहीं करेगा: ऑन टच ऑनक्लिक लिस्टनर की विधि नहीं है। और मुझे अभी भी ट्रैकबॉल का उपयोग करने वाले लोगों के लिए अभी भी आवश्यकता है। कोई अन्य विचार लोग? – Octoth0rpe

+0

मेरा मतलब है कि आप अपने टच विधि को छोड़ दें, लेकिन उस कोड के टुकड़े को हटा दें जो पृष्ठभूमि से बदलता है। अतिरिक्त में, क्लिक श्रोता (यानी yourView.setOnClickListener (नया ऑनक्लिक ....) पर दृश्य सेट करें और इसे खाली छोड़ दें। इस तरह आपके पास प्रेस प्रभाव होगा। – Givi

+0

मैं उपर्युक्त पुष्टि कर सकता हूं कि काम नहीं करता है :(@ Octoth0rpe: क्या आपको कोई कामकाज मिला? –

2

मैं यह पता लगा!

@Override 
public boolean onTouch(View v, MotionEvent event) { 
    if(event.getAction() == MotionEvent.ACTION_DOWN){ 
     yourView.setSelected(true); 
     ... 
     return true; 
    } 
    else if(event.getAction() == MotionEvent.ACTION_UP){ 
     yourView.setSelected(false); 
     ... 
     return true; 
    } 
    else 
     return false; 
} 

कि अपने चयनकर्ता काम आपके विचार एक onTouch श्रोता :)

3

onTouchListener() फ़ंक्शन के अंत में false वापस जाने के लिए सुनिश्चित करें कि है, भले ही बनाती हूँ: इस प्रकार बस view.setSelected() का उपयोग करें। :)

1

बेहतर समाधान:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" > 
    <item android:state_activated="true"> 
     <bitmap android:src="@drawable/image_selected"/> 
    </item> 
    <item> 
     <bitmap android:src="@drawable/image_not_selected"/> 
    </item> 
</selector> 

@Override 
public void onClick(View v) { 
    if (v.isActivated()) 
     v.setActivated(false); 
    else 
     v.setActivated(true); 
}