software - android system download




findViewByID शून्य वापस आता है (17)

जो शून्य वापस आता है

संभवतः क्योंकि आप इसे बहुत जल्दी बुला रहे हैं। onFinishInflate() प्रतीक्षा करें। यहां एक नमूना प्रोजेक्ट है जो एक कस्टम View अपनी सामग्री तक पहुंचने का प्रदर्शन करता है।

सबसे पहले: हाँ, मैंने इस विषय पर अन्य सभी धागे पढ़े हैं। और न केवल इस साइट के लोग ... (आप देखते हैं, मैं थोड़ा निराश हूँ)

उनमें से अधिकतर XML फ़ाइल में केवल id बजाय android:id का उपयोग करने की सलाह के साथ आते हैं। मैंने किया।

दूसरों से, मैंने सीखा, कि View.findViewById Activity.findViewById से अलग काम करता है। मैंने भी इसे संभाला।

मेरे location_layout.xml , मैं उपयोग करता हूं:

<FrameLayout .... >
    <some.package.MyCustomView ... />

    <LinearLayout ... >
        <TextView ...
            android:id="@+id/txtLat" />
        ...
    </LinearLayout>
</FrameLayout>

मेरी गतिविधि में मैं करता हूं:

...
setContentView( R.layout.location_layout );

और मेरे कस्टम व्यू क्लास में:

... 
TextView tv = (TextView) findViewById( R.id.txtLat );

जो null वापस आता है। ऐसा करने से, मेरी गतिविधि ठीक काम करती है। तो हो सकता है कि यह Activity.findViewById और View.findViewById अंतरों के कारण है। तो मैंने स्थानीय रूप से रीति-रिवाज कन्स्ट्रक्टर को पारित संदर्भ संग्रहीत किया और कोशिश की:

...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );

जो भी null वापस आ गया।

फिर, मैंने View ViewGroup को विस्तारित करने के लिए अपना कस्टम View बदल दिया और View.findViewById को मेरे कस्टम व्यू का प्रत्यक्ष बच्चा होने के लिए location_layout.xml को बदल दिया और View कि View.findViewById को View.findViewById ही काम करना चाहिए। Suprise: यह कुछ भी हल नहीं किया था।

तो क्या बिल्ली मैं गलत कर रहा हूँ?

मैं किसी भी टिप्पणी की सराहना करूंगा।


अगर आप एक टुकड़े के अंदर हैं तो findViewById भी शून्य वापस कर सकता है। जैसा कि यहां वर्णित है: Fragment में findViewById खोजें

आपको Fragment के अंदर शीर्ष स्तर दृश्य को वापस करने के लिए getView () को कॉल करना चाहिए। फिर आप लेआउट आइटम (बटन, टेक्स्टव्यू, आदि) पा सकते हैं


एक लेआउट संसाधन से गतिविधि सामग्री सेट करें। यानी, setContentView(R.layout.basicXml) ;


एफडब्ल्यूआईडब्ल्यू, मुझे नहीं लगता कि किसी ने इसे वैसे ही हल किया जैसा मुझे चाहिए था। संकलन समय पर कोई शिकायत नहीं है, लेकिन मुझे रनटाइम पर एक नज़र दृश्य मिल रहा था, और उचित क्रम में चीजों को बुला रहा था। यही है, setViewById () setContentView () के बाद । समस्या यह साबित हुई कि मेरा विचार content_main.xml में परिभाषित किया गया है, लेकिन मेरी गतिविधि_main.xml में, मुझे यह एक कथन नहीं था:

<include layout="@layout/content_main" />

जब मैंने गतिविधि_main.xml में जोड़ा, अब और नलपॉइंटर नहीं।


बस यहां मेरा विशिष्ट मामला फेंकना चाहता था। किसी को लाइन के नीचे मदद कर सकते हैं।

मैं अपने एंड्रॉइड यूआई एक्सएमएल में इस तरह के निर्देश का उपयोग कर रहा था:

अभिभावक दृश्य:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="home_phone"
    android:background="@color/colorPrimary">

    ...

    <include
        layout="@layout/retry_button"
        android:visibility="gone" />

बाल दृश्य (retry_button):

<com.foo.RetryButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/retry"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:layout_width="100dp"
    android:layout_height="140dp">

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

निश्चित माता-पिता:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="home_phone"
    android:background="@color/colorPrimary">

    ...

    <include
        layout="@layout/retry_button"
        android:id="@+id/retry"
        android:visibility="gone" />

निश्चित बच्चा:

<com.foo.RetryButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:layout_width="100dp"
    android:layout_height="140dp">

मुझे एक ही समस्या है, लेकिन मुझे लगता है कि यह आपके साथ लोगों के साथ साझा करने लायक है। यदि आपको कस्टम लेआउट में ViewById मिलना है, उदाहरण के लिए:

public class MiniPlayerControllBar extends LinearLayout {
    //code
}

आप कन्स्ट्रक्टर में दृश्य नहीं प्राप्त कर सकते हैं। देखने के बाद आपको findViewById को कॉल करना चाहिए। उनकी एक विधि है जिसे आप onFinishInflate ओवरराइड कर सकते हैं


मेरा फिक्स सिर्फ परियोजना को साफ करना था।


मेरा मामला उपरोक्त की तरह कोई नहीं है, कोई समाधान काम नहीं करता है। मुझे लगता है कि मेरा विचार लेआउट पदानुक्रम में बहुत गहरा था। मैंने इसे एक स्तर ऊपर ले जाया और यह अब शून्य नहीं था।


मेरे मामले में मैंने लेआउट बढ़ाया था लेकिन बच्चे के विचार शून्य लौट रहे थे। मूल रूप से मेरे पास यह था:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_history);

    footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
    pbSpinner = (ProgressBar) findViewById(R.id.pbListviewFooter);
    tvText = (TextView) findViewById(R.id.tvListviewFooter);
    ...
}

हालांकि, जब मैंने इसे निम्नलिखित में बदल दिया तो यह काम करता था:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_history);

    footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false);
    pbSpinner = (ProgressBar) footerView.findViewById(R.id.pbListviewFooter);
    tvText = (TextView) footerView.findViewById(R.id.tvListviewFooter);
    ...
}

कुंजी को विशेष रूप से पहले से फुले हुए लेआउट को संदर्भित करना था ताकि बच्चे के विचार प्राप्त हो सकें। यही है, footerView जोड़ने के लिए:

  • footerView .findViewById ...

मेरे मामले में, मेरे प्रोजेक्ट, main.xml और main2.xml में 2 main2.xml । शुरुआत से, main की एक प्रति थी, और जब तक मैंने main main2 नया main2 जोड़ा, तब तक सब कुछ ठीक से काम main2 , इसलिए R.id.textview1 शेष ऐप के लिए उपलब्ध हो गया। तब मैंने इसे मानक कॉलिंग द्वारा लाने की कोशिश की:

TextView tv = (TextView) findViewById( R.id.textview1 );

और यह हमेशा शून्य था। यह पता चला कि main2 कन्स्ट्रक्टर में मैं main2 नहीं कर रहा था, लेकिन दूसरा। मैंने लिया:

setContentView(R.layout.main);

के बजाय

setContentView(R.layout.main2);

साइट पर आने के बाद मैंने यह देखा।


मेरे लिए मेरे पास एक ही गतिविधि के लिए दो एक्सएमएल लेआउट थे - एक पोर्ट्रेट मोड में और एक परिदृश्य में। बेशक मैंने लैंडस्केप एक्सएमएल में किसी ऑब्जेक्ट की आईडी बदल दी थी लेकिन पोर्ट्रेट संस्करण में वही बदलाव करना भूल गया था। सुनिश्चित करें कि यदि आप एक को बदलते हैं तो आप अन्य एक्सएमएल पर ऐसा करते हैं या जब तक आप इसे चलाते / डीबग नहीं करते हैं तब तक आपको कोई त्रुटि नहीं मिलेगी और यह वह आईडी नहीं मिल सकती है जिसे आपने नहीं बदला था। ओह गूंगा गलतियों, तुम मुझे इतना दंड क्यों देना चाहिए?


मेरे विशेष मामले में, मैं एक सूची दृश्य में एक पाद लेख जोड़ने की कोशिश कर रहा था। क्रिएट () पर निम्नलिखित कॉल शून्य लौट रही थी।

TextView footerView = (TextView) placesListView.findViewById(R.id.footer);

आईडी द्वारा इसे खोजने के बजाए पाद लेख दृश्य को बढ़ाने के लिए इसे बदलना इस समस्या को हल करता है।

View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false);

मैंने उपर्युक्त सभी काम करने की कोशिश की है .. इसलिए मुझे अपना इमेज व्यू स्थिर public static ImageView texture; दृश्य बना देना पड़ा public static ImageView texture; और उसके बाद texture = (ImageView) findViewById(R.id.texture_back); , मुझे नहीं लगता कि यह एक अच्छा दृष्टिकोण है, लेकिन यह वास्तव में मेरे मामले के लिए काम किया :)


यदि आप कस्टम दृश्य में गलत सुपर कन्स्ट्रक्टर को कॉल करते हैं तो FindViewById शून्य हो सकता है। आईडी टैग attrs का हिस्सा है, इसलिए यदि आप attrs को अनदेखा करते हैं, तो आप आईडी हटाते हैं।

यह गलत होगा

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

यह सही है

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

संभवतः, आप setContentView को कॉल findViewById से पहले findViewById को कॉल कर रहे हैं? यदि ऐसा है, तो setContentView कॉल करने के बाद findViewById कॉल करने का प्रयास करें


सुनिश्चित करें कि आपके पास अलग-अलग स्क्रीन घनत्व के लिए आपके लेआउट के एकाधिक संस्करण नहीं हैं। एक बार मौजूदा आईडी में एक नई आईडी जोड़ते समय मैं इस समस्या में भाग गया लेकिन एचडीपीआई संस्करण को अपडेट करना भूल गया। यदि आप लेआउट फ़ाइल के सभी संस्करणों को अपडेट करना भूल जाते हैं तो यह कुछ स्क्रीन घनत्व के लिए काम करेगा लेकिन दूसरों को नहीं।


    @Override
protected void onStart() {
         // use findViewById() here instead of in onCreate()
    }




android