Android बटन में setOnTouchListener कहा गया है, लेकिन यह PerformClick को ओवरराइड नहीं करता है


113

जब मैं onTouchListner()एक बटन जोड़ने की कोशिश करता हूं , तो यह मुझे मिल जाता है

बटन में setOnTouchListener है, इस पर कॉल किया गया है, लेकिन PerformClick को ओवरराइड नहीं करता है

चेतावनी। क्या किसी को पता है कि इसे कैसे ठीक करना है?

1

btnleftclick.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return false;
    }
});

त्रुटि:

कस्टम दृश्य में setOnTouchListener इस पर कॉल किया गया है, लेकिन प्रदर्शन को ओवरराइड नहीं करता है। यदि कोई दृश्य जो onTouchEvent को ओवरराइड करता है या OnTouchListener का उपयोग करता है, तो भी प्रदर्शन को लागू नहीं करता है और क्लिक का पता चलने पर उसे कॉल करता है, दृश्य ठीक से पहुंच योग्य क्रियाओं को ठीक से नहीं देख सकता है। क्लिक क्रियाओं को संभालने वाले तर्क को आदर्श रूप से # # प्रदर्शन में रखा जाना चाहिए क्योंकि क्लिक की क्रिया होने पर कुछ पहुँच सेवाएँ प्राप्त होती हैं।


कस्टम दृश्य ImageViewमें setOnTouchListener इस पर कॉल किया गया है, लेकिन प्रदर्शन को ओवरराइड नहीं करता है। यदि कोई दृश्य जो onTouchEvent को ओवरराइड करता है या OnTouchListener का उपयोग करता है, तो भी प्रदर्शन को लागू नहीं करता है और क्लिक का पता चलने पर उसे कॉल करता है, दृश्य ठीक से पहुंच योग्य क्रियाओं को ठीक से नहीं देख सकता है। क्लिक क्रियाओं को संभालने वाले लॉजिक को आदर्श रूप से # प्रदर्शन में रखा जाना चाहिए क्योंकि क्लिक एक्शन होने पर कुछ एक्सेसिबिलिटी सेवाएं परफॉर्म करती हैं।
क्स

कृपया मेरा जवाब यहां देखें: stackoverflow.com/questions/47170075/…
लंबू

जवाबों:


134

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

पहुँच योग्य सेवाओं के माध्यम से नेत्रहीन उपयोगकर्ताओं को उचित प्रतिक्रिया प्रदान करने के लिए मानक यूआई दृश्य (जैसे Button, TextViewआदि) स्थापित किए जाते हैं। जब आप अपने आप को स्पर्श घटनाओं को संभालने की कोशिश करते हैं, तो आप उस प्रतिक्रिया को प्रदान करने के लिए भूल जाने के खतरे में हैं। यह चेतावनी के लिए है।

विकल्प 1: एक कस्टम दृश्य बनाएं

स्पर्श घटनाओं को संभालना आम तौर पर एक कस्टम दृश्य में किया जाता है। इस विकल्प को भी जल्दी से खारिज न करें। यह वास्तव में मुश्किल नहीं है। यहाँ एक पूर्ण उदाहरण है TextViewकि स्पर्श घटनाओं को संभालने के लिए ओवरराइड किया गया है:

public class CustomTextView extends AppCompatTextView {

    public CustomTextView(Context context) {
        super(context);
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                return true;

            case MotionEvent.ACTION_UP:
                performClick();
                return true;
        }
        return false;
    }

    // Because we call this from onTouchEvent, this code will be executed for both
    // normal touch events and for when the system calls this using Accessibility
    @Override
    public boolean performClick() {
        super.performClick();
        doSomething();
        return true;
    }

    private void doSomething() {
        Toast.makeText(getContext(), "did something", Toast.LENGTH_SHORT).show();
    }
}

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

<com.example.myapp.CustomTextView
    android:id="@+id/textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="20dp"
    android:text="Click me to do something"/>

देखें मेरे दूसरे सवाल का जवाब एक कस्टम दृश्य बनाने के बारे में अधिक जानकारी के लिए।

विकल्प 2: चेतावनी को शांत करना

अन्य बार चेतावनी को चुप कराना बेहतर होगा। उदाहरण के लिए, मुझे यकीन नहीं है कि आप क्या करना चाहते हैं, इसके लिए Buttonआपको स्पर्श घटनाओं की आवश्यकता है। आप एक कस्टम बटन बनाने के लिए थे और कहा जाता है तो performClick()में onTouchEventजैसे मैं कस्टम के लिए ऊपर किया TextViewहै, तो यह दो बार हर बार बुलाया जायेगा क्योंकि Buttonपहले से ही कहता है performClick()

यहाँ कुछ कारण दिए गए हैं जिनसे आप चेतावनी को चुप करा सकते हैं:

  • आप अपने स्पर्श कार्यक्रम के साथ जो कार्य कर रहे हैं वह केवल दृश्य है। यह आपके ऐप के वास्तविक कार्य को प्रभावित नहीं करता है।
  • आप ठंडे दिल के हैं और दुनिया को अंधे लोगों के लिए एक बेहतर जगह बनाने की परवाह नहीं करते हैं।
  • ऊपर दिए गए विकल्प 1 में आपके द्वारा दिए गए कोड को कॉपी और पेस्ट करने के लिए आप बहुत आलसी हैं।

चेतावनी को दबाने के लिए विधि की शुरुआत में निम्नलिखित पंक्ति जोड़ें:

@SuppressLint("ClickableViewAccessibility")

उदाहरण के लिए:

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

    Button myButton = findViewById(R.id.my_button);
    myButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            return false;
        }
    });
}

1
मैं अलग-अलग फोंट का उपयोग करने के कारण कस्टमाइज़ का उपयोग कर रहा था। जैसा कि अब Api 26 में नए फीचर, xml में फोंट और पुराने वर्जन के लिए सपोर्ट लाइब्रेरी 26 का इस्तेमाल किया गया है जो Api 16 तक सपोर्ट करता है। इसलिए मैंने सभी कस्टम व्यूज को हटा दिया है। और यह बेवकूफाना चेतावनी सामने आई है और इसका समाधान फिर से उन कुछ कस्टम विचारों को बनाना है जिनके लिए मैं setOnTouchListener का उपयोग कर रहा हूं।
हाहाहा

19
मुझे आश्चर्य है कि अगर Google को पता चलता है कि वे कितने डेवलपर घंटे बर्बाद करते हैं। मेरा मतलब है, वे शायद आपी के भीतर इसे संभाल सकते हैं? विचारों को कम करने या अपनी चेतावनी को हल करने के तरीके को खोजने में समय व्यतीत करना बहुत सारे घंटे बर्बाद करता है।
TatiOverflow

क्या होगा यदि आपको MotionEvent eventअपनी doSomething()विधि में ऑब्जेक्ट की आवश्यकता है ? मुझे जाँच करने की आवश्यकता है event.getY()
मटुस गोंडिम

@ मट्टुसगोंडिम, मेरा कहना है कि मैं अभी भी इसे लागू करने में बहुत सक्षम नहीं हूं performClick()। मेरा प्रारंभिक विचार यह है कि यदि event.getY()वास्तविक क्लिक ईवेंट (यानी विज़ुअल यूआई इफ़ेक्ट) से अभिन्न नहीं है, तो उस तर्क को वापस ले जाएं onTouchEvent()। अन्यथा आप अंतिम क्रिया अप Yमूल्य को संग्रहीत करने के लिए एक वर्ग सदस्य चर बना सकते हैं । मेरा सुझाव है कि आप कुछ मानक विचारों के लिए स्रोत कोड की जांच करें ताकि देखें कि एंड्रॉइड इसे कैसे लागू करता है। मुझे उन्हें स्वयं अधिक अध्ययन करने की आवश्यकता है।
सुरगाछ

1
@ सिसिसिसि, चेतावनी तब सामने आती है जब आप ओवरराइड करते हैं onTouchEvent()लेकिन नहीं performClick()। जिसमें एक स्वाइप या क्लिक या कोई अन्य स्पर्श घटना शामिल हो सकती है जिसे आप कैप्चर करने का प्रयास कर रहे हैं।
सूर्याग

17

उपाय:

  1. एक वर्ग बनाएं जो बटन का उपयोग करता है या जो भी दृश्य आप उपयोग कर रहे हैं और प्रदर्शन को ओवरराइड करें ()

    class TouchableButton extends Button {
    
        @Override
        public boolean performClick() {
            // do what you want
            return true;
        }
    }
    
  2. अब इस TouchableButton का उपयोग xml और / या कोड में करें और चेतावनी समाप्त हो जाएगी!


18
यह वास्तव में स्थूल है। क्या मौजूदा विचारों का उपयोग करने का कोई तरीका नहीं है?
दूध

@ माइलक नोप। android.widget.Buttonहार्डकोड है इसलिए यह आपको ऐसा करने की अनुमति नहीं देता है। और यह एंड्रॉइड देव टीम से बहुत जानबूझकर लगता है।
tom_mai78101

11

क्या आपने जोड़ने की कोशिश की है:

view.performClick()

या दमन एनोटेशन जोड़ना:

@SuppressLint("ClickableViewAccessibility")

?


2
हाँ। एंड्रॉइड स्टूडियो 3.0 संस्करण
कास

1
ठीक है, मेरे पास उस चेतावनी को ठीक करने का एक विकल्प है। कृपया देखें: stackoverflow.com/questions/47170075/…
lambda

1

कस्टम दृश्य नियंत्रण के लिए गैर-मानक स्पर्श ईवेंट व्यवहार की आवश्यकता हो सकती है। उदाहरण के लिए, एक कस्टम नियंत्रण ACTT_DOWN और ACTION_UP घटनाओं का पता लगाने और एक विशेष क्लिक ईवेंट को ट्रिगर करने के लिए onTouchEvent (MotionEvent) श्रोता विधि का उपयोग कर सकता है। एक्सेसिबिलिटी सेवाओं के साथ संगतता बनाए रखने के लिए, इस कस्टम क्लिक इवेंट को संभालने वाले कोड को निम्न कार्य करने होंगे:

व्याख्या की गई क्लिक क्रिया के लिए एक उपयुक्त पहुँच क्षमता बनाएँ। उन उपयोगकर्ताओं के लिए कस्टम क्लिक कार्रवाई करने के लिए पहुंच सेवाओं को सक्षम करें जो टच स्क्रीन का उपयोग करने में सक्षम नहीं हैं। इन आवश्यकताओं को एक कुशल तरीके से संभालने के लिए, आपके कोड को performClick () विधि को ओवरराइड करना चाहिए, जिसे इस पद्धति के सुपर कार्यान्वयन को कॉल करना होगा और फिर क्लिक ईवेंट द्वारा आवश्यक कार्यों को निष्पादित करना होगा। जब कस्टम क्लिक एक्शन का पता चलता है, तो उस कोड को तब आपकी परफॉर्मेकल () विधि को कॉल करना चाहिए।

https://developer.android.com/guide/topics/ui/accessibility/custom-views#custom-touch-events

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