FindViewById का परिणाम डालने की आवश्यकता नहीं है?


152

हाल ही में मैंने पाया कि AndroidStudio मुझे कुछ क्लास कास्ट हटाने के लिए याद दिलाता है। मुझे याद है कि पुराने समय में, हमें findViewById का परिणाम देना होगा, लेकिन अब यह आवश्यक नहीं है।

FindViewById का परिणाम अभी भी दृश्य है, इसलिए मैं जानना चाहता हूं कि हमें कक्षा में डालने की आवश्यकता क्यों नहीं है?

मैं किसी भी दस्तावेज का उल्लेख नहीं कर सकता हूँ, क्या कोई भी कोई भी दस्तावेज़ पा सकता है?


7
क्योंकि अब यह है <T extends View> T findViewById(int id)?
सेल्विन

आपको किसी भी ऑपरेशन के मामले में कास्टिंग की आवश्यकता है, जो व्यू क्लास में नहीं है, जैसे कि ImageView के मामले में, यदि आप setImageResource का उपयोग करना चाहते हैं, तो आपको ImageView के साथ findViewById को डालना होगा
गगन दीप

लेकिन मुझे "अनावश्यक" कास्टिंग को हटा देने पर एक नज़र में चर प्रकार जानने में थोड़ी असुविधा महसूस होती है।
फ्रूट

जवाबों:


235

एपीआई 26 के साथ शुरू, findViewByIdइसके वापसी प्रकार के लिए प्रवेश का उपयोग करता है, इसलिए आपको अब कास्ट नहीं करना होगा।

पुरानी परिभाषा:

View findViewById(int id)

नई परिभाषा:

<T extends View> T findViewById(int id)

तो अगर आपका compileSdkकम से कम 26 है, तो इसका मतलब है कि आप इस का उपयोग कर सकते हैं :)


धन्यवाद, और एक और सवाल। मैं sdk26 के लिए sdk प्रबंधक में स्रोत नहीं खोज सकता, तो मुझे यह नई परिभाषा कहाँ मिल सकती है?
एरिक झाओ

17
यदि हम कलाकारों को हटाते हैं, तो हमारे एप्लिकेशन अभी भी निचले उपकरणों पर चल सकते हैं, है ना?
user1032613

17
@ user1032613: हाँ ऐप्स अभी भी बिना किसी समस्या के निचले उपकरणों पर काम कर सकते हैं।
एलिरेज़ा नूराली

1
यदि यह गलत प्रकार है तो क्या यह एक अपवाद को फेंक देगा?
फोबाइमास्टर

1
जैसे कि लेआउट फ़ाइल में दृश्य भिन्न प्रकार का है? हां, निश्चित रूप से, यह अभी भी एक होगा ClassCastException
एडुआर्ड बी।

13

इस लेख के अनुसार :

मैनुअल कास्टिंग की आवश्यकता को समाप्त करने के लिए निम्नलिखित फ़ंक्शन जावा के जेनरिक स्वचालित प्रकार के निष्कर्ष पर निर्भर करता है:

protected <T extends View> T findViewById(@IdRes int id) {
    return (T) getRootView().findViewById(id);
}

11

पुराने संस्करणों में:

AutoCompleteTextView name = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);

एसडीके 26 के साथ एंड्रॉइड स्टूडियो 3.0 से:

AutoCompleteTextView name = findViewById(R.id.autoCompleteTextView);

16
यह प्रश्न का उत्तर प्रदान नहीं करता है।
विजेय शर्मा

1

एंड्रॉइड स्टूडियो कास्टिंग को हटाने की याद दिलाता है, यदि आप दृश्य वर्ग से सामान्य विशेषताओं का उपयोग करते हैं , जैसे दृश्यता या कुछ सामान्य तरीके, जैसे onClick ()

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

((ImageView) findViewById(R.id.image_car)).setVisibility(View.VISIBLE);

इस मामले में आप बस लिख सकते हैं:

findViewById(R.id.image_car).setVisibility(View.VISIBLE);

2
आपको अभी भी प्रकार घोषित करना है, आपको लिखना होगा: findViewById <ImageView> (R.id.image_car) .setVisibility (View.VISIBLE);
स्लिकेलिटो

एंड्रॉइड स्टूडियो हमें स्पष्ट कास्टिंग को हटाने की याद दिलाता है क्योंकि यह जावा के जेनरिक ऑटोमैटिक प्रकार के निष्कासन के कार्यान्वयन में बदल गया है - इसका आपके द्वारा उपयोग की जाने वाली विधि से कोई लेना-देना नहीं है।
जीरो डिवाइडर

1

एंड्रॉइड 0, क्लीन अप कास्टिंग

IO 2017 में Google द्वारा घोषित चीजों में से एक ऐसी चीज है जिसे 'कास्ट दूर' कहा जाता है :)। Android डेवलपर को FindViewById () के लिए मैन्युअल कास्टिंग करने की आवश्यकता नहीं है। उदाहरण के लिए findViewById () का उपयोग करके टेक्स्ट दृश्य प्राप्त करने का पुराना तरीका कुछ इस तरह होगा।

TextView txtDesc = (TextView) findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));

जबकि नया तरीका इस तरह होगा

TextView txtDesc = findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));

यह एक साधारण बदलाव है। लेकिन एक अनुभवी प्रोग्रामर के लिए, इस तरह का एक साफ कोड आपको बहुत खुश कर सकता है और यह आपके कोडिंग मूड के साथ मदद करता है :)

ऐसा करने में सक्षम होने के लिए आपको केवल अपनी परियोजना संकलित एसडीके संस्करण को अपने ऐप बिल्ड 26 में सेट करने की आवश्यकता है ।ग्रेड।

आप अभी भी पहले के एसडीके संस्करण को भी लक्षित कर सकते हैं, इसलिए यह एक गैर-घुसपैठिया बदलाव है।

अब असली समस्या, आप उस पुराने कोड को कैसे साफ़ करते हैं जो इस समय सभी कास्टिंग का उपयोग करता है। खासकर जब आपको सैकड़ों एक्टिविटी फाइल्स पसंद हों। आप इसे मैन्युअल रूप से कर सकते हैं, या शायद इसे करने के लिए एक इंटर्न को काम पर रखा है,। लेकिन सौभाग्य से उन सभी इंटर्न के लिए, एंड्रॉइड स्टूडियो ने पहले से ही हमारी मदद करने के लिए तैयार किया।

जब आप अपना कैरेट डालते हैं (या निरर्थक कास्टिंग पर क्लिक करते हैं) तो एंड्रॉइड स्टूडियो निरर्थक कास्टिंग को संभालने के लिए 2 विकल्प सुझाएगा।

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

इंटेलीज विचार को विशेष बनाने वाली चीजों में से एक यह है कि एक विशेषता जिसे इरादतन कार्रवाई कहा जाता है। आपको बस इतना करना है कि ctrl + shift + A पुश करें और फिर क्लीन टाइप करें। और कोड क्लीन अप एक्शन का चयन करें, और पूरे प्रोजेक्ट स्कोप का चयन करें। इस कुछ सरल चरणों के साथ आपका कोड पूरी तरह से क्लीनर होगा।

एक महत्वपूर्ण बिंदु यह है कि आप कुछ कोड संस्करण प्रणाली के साथ ऐसा करते हैं। इस तरह आप उन परिवर्तनों की तुलना कर सकते हैं जो इरादे कार्रवाई द्वारा किए जा रहे हैं और आप जो भी फाइल चाहते हैं उसे वापस कर सकते हैं।

मूल पोस्ट से कॉपी किया गया:

https://medium.com/@abangkis/android-0-clean-up-casting-c30acec56cef


1
सवाल यह था कि whyनहीं how:The result of findViewById is still View, so i want to know why we don't need to cast the class?
जीरो डिवाइडर

"आपको बस इतना करना है कि ctrl + shift + A पुश करें और फिर क्लीन टाइप करें"। "टाइप क्लीन" से आपका क्या अभिप्राय है? यदि आप उस बिंदु पर लिखना शुरू करते हैं, तो आप पूरी फ़ाइल मिटा देंगे
चुपके रब्बी

0

के स्रोत कोड में ViewGroup, रिटर्न तर्क का एक अंश है। तो फिर से डालने की कोई आवश्यकता नहीं है:

@Nullable
public final <T extends View> T findViewById(@IdRes int id) {
    if (id == NO_ID) {
        return null;
    }
    return findViewTraversal(id);
}

@Override
protected <T extends View> T findViewTraversal(@IdRes int id) {
    if (id == mID) {
        return (T) this;  //###### cast to T
    }

    final View[] where = mChildren;
    final int len = mChildrenCount;

    for (int i = 0; i < len; i++) {
        View v = where[i];

        if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
            v = v.findViewById(id);

            if (v != null) {
                return (T) v; //###### cast to T
            }
        }
    }

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