OnClickListener के अंदर मैं बहुत सी चीजों तक नहीं पहुँच सकता - कैसे संपर्क करें?


79

OnClickListener के अंदर मैं इस तरह के अधिकांश "चर" दायरे के बाहर नहीं जा सकता, जैसे:

findViewById(R.id.Button01).setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Intent mainApps = new Intent(Intent.ACTION_MAIN);
                mainApps.addCategory(Intent.CATEGORY_LAUNCHER);
                List<ActivityInfo> activities = this.getPackageManager().queryIntentActivities(mainApps, 0);
                /*
                Intent intent = new Intent("com.sygic.drive/com.sygic/drive/.SygicDriveActivity");
                startActivity(intent);*/
            }

        });

इस उदाहरण में मुझे PacketManager को प्राप्त करने की आवश्यकता है, और मैं इसे प्राप्त नहीं कर सकता क्योंकि मेरे पास OnClickListener के अंदर संदर्भ उपलब्ध नहीं है।

मैं बाहर एक स्थैतिक संदर्भ बना सकता हूं, और इसे अंदर उपयोग कर सकता हूं, लेकिन क्या यह सही है? हर समय ऐसा करना अजीब लगता है?

जवाबों:


231

thisअपने कोड में बदलें MyActivity.thisजहाँ MyActivity आपकी गतिविधि उपवर्ग का वर्ग नाम है।

स्पष्टीकरण: जब आप अपने कोड के इस हिस्से का उपयोग करते हैं तो आप एक अनाम आंतरिक वर्ग बना रहे हैं:
new OnClickListener() {
अनाम आंतरिक कक्षाओं में उनके द्वारा बनाए गए वर्ग के उदाहरण का संदर्भ होता है। ऐसा लगता है कि आप इसे एक गतिविधि उपवर्ग के अंदर बना रहे हैं क्योंकि findViewByd एक है गतिविधि विधि। गतिविधि एक संदर्भ है, इसलिए आपको बस इसके लिए संदर्भ का उपयोग करना होगा जो आपके पास है।


1
मैं थोड़ी देर के लिए "MyActivity.this" खोजने के लिए गुगली कर रहा हूं। यह अब बहुत आसान लगता है। जानकारी के लिए धन्यवाद!
TCCV

उन वैरिएबल के बारे में क्या जो त्रुटि देते हैं Cannot refer to a non-final variable table inside an inner class defined in a different method? मैं उन लोगों तक नहीं पहुँच सकता MyActivity.this
माइकल

वे स्थानीय चर हैं। यदि वे नहीं बदलते हैं, तो आप उनमें अंतिम होने की घोषणा को बदल सकते हैं। यदि वे परिवर्तन करते हैं, लेकिन इससे पहले कि आपके आंतरिक वर्ग को परिभाषित किया जाए, आप बस एक अंतिम संस्करण को ठीक पहले परिभाषित कर सकते हैं। जैसे: अंतिम int myFinalErrorCode = errorCode। अन्यथा आपको उस गतिविधि पर एक सदस्य बनाना और सेट करना होगा जिसे आप एक्सेस करते हैं या आंतरिक वर्ग में करते हैं।
लांस नानक

मुझे यह समझ में नहीं आता है, लेकिन यह आपके कहे अनुसार काम करता है Activity.this.doStg()। क्या आप यहां बता सकते हैं @LanceNanek कृपया अधिक विस्तृत विवरण के साथ कुछ यूआरएल। क्या यह किसी भी तरह प्रतिक्रियाशील प्रोग्रामिंग से संबंधित है?
7:16 पर मर्ट

यहां "ShadowTest.this" उदाहरण देखें: docs.oracle.com/javase/tutorial/java/javaOO/nested.html
लांस नानक

10

आप अपनी कक्षा में OnClickListener इंटरफ़ेस को लागू कर सकते हैं और एक अनाम आंतरिक वर्ग की आवश्यकता से बच सकते हैं। फिर आप क्लिक श्रोता को इस तरह सेट करेंगे:

findViewById(R.id.Button01).setOnClickListener(this);

यदि आपके पास एक श्रोता का उपयोग करने वाले कई बटन हैं, तो आप उनके बीच अंतर करने के लिए view.getId () (जो R.id में दृश्य आईडी से मेल खाती है) के साथ एक स्विच स्टेटमेंट का उपयोग कर सकते हैं।


4

कुछ चीजें हैं जो आप कर सकते हैं, आप एक आंतरिक वर्ग बना सकते हैं जो onClickListener को लागू करता है और कक्षा के निर्माता में आवश्यक तर्क देता है। मुझे अभी भी सबसे साफ तरीका नहीं मिला है। मैं आमतौर पर अपनी कार्रवाई करने के लिए एक और तरीका बनाता हूं। इसलिए onClick (देखें v) मैं कुछ ऐसा करूंगा।

onClick(View v){doMyAction(myParams)}

private void doMyAction(Object params){//do stuff}

और श्रोता विधि से श्रोता के बाहर विधि के लिए आवश्यक पैरामेट्स को पास करें।


ठीक है, अजीब ताहट आपको ऐसा करना होगा, लेकिन मुझे लगता है कि यह काम करता है। =)
टेड

0

आशय (संदर्भ, वर्गनाम) के उपयोग में आशय निर्माणकर्ता को बदलें और अपने इनरक्लास में getApplicationContext () का उपयोग करें। मेरी समस्या का समाधान किया।

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