निर्दिष्ट बच्चे के पास पहले से ही एक माता-पिता हैं। आपको पहले बच्चे के माता-पिता (एंड्रॉइड) पर removeView () कॉल करना होगा


164

मुझे अक्सर दो लेआउट के बीच स्विच करना पड़ता है। नीचे पोस्ट किए गए लेआउट में त्रुटि हो रही है।

जब मेरे लेआउट को पहली बार कहा जाता है, तो कोई त्रुटि नहीं होती है और सब कुछ ठीक है। जब मैं एक अलग लेआउट (एक रिक्त एक) को कॉल करता हूं और बाद में अपने लेआउट को दूसरी बार कॉल करता हूं, तो यह निम्न त्रुटि फेंकता है:

> FATAL EXCEPTION: main
>     java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

मेरा लेआउट-कोड इस तरह दिखता है:

    tv = new TextView(getApplicationContext()); // are initialized somewhere else
    et = new EditText(getApplicationContext()); // in the code


private void ConsoleWindow(){
        runOnUiThread(new Runnable(){

     @Override
     public void run(){

        // MY LAYOUT:
        setContentView(R.layout.activity_console);
        // LINEAR LAYOUT
        LinearLayout layout=new LinearLayout(getApplicationContext());
        layout.setOrientation(LinearLayout.VERTICAL);
        setContentView(layout);

        // TEXTVIEW
        layout.addView(tv); //  <==========  ERROR IN THIS LINE DURING 2ND RUN
        // EDITTEXT
        et.setHint("Enter Command");
        layout.addView(et);
        }
    }
}

मुझे पता है कि यह सवाल पहले भी पूछा जा चुका है, लेकिन इसने मेरे मामले में मदद नहीं की।


1
बस उसी त्रुटि वाले व्यक्ति के लिए: सुनिश्चित करें कि आप सही तत्व जोड़ते हैं। कहते हैं कि आपको जोड़ना है LinearLayoutलेकिन आप जोड़ते हैं TextView। तो इसे ठीक करें।
डेवलपर

जब एंड्रॉइड डेटाबाइंडिंग का उपयोग आईडी 'रूट' के साथ देखने की घोषणा नहीं करनी चाहिए, तो यह उसी त्रुटि का कारण बनता है।
मोहम्मद रज़ा ख़ानी

उपयोग करने वालों के लिए TranstitionManager.beginDelayedTransition, कृपया मेरे उत्तर को यहाँ देखें
mochadwi

जवाबों:


354

त्रुटि संदेश कहता है कि आपको क्या करना चाहिए।

// TEXTVIEW
if(tv.getParent() != null) {
    ((ViewGroup)tv.getParent()).removeView(tv); // <- fix
}
layout.addView(tv); //  <==========  ERROR IN THIS LINE DURING 2ND RUN
// EDITTEXT

56

बस संलग्नक तर्क को असत्य के रूप में पास करें

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false);

2
मेरे लिए, यह एक बकवास था। पुनरावृत्ति में वस्तुओं के लिए बाधा लेआउट, रनटाइम के आधार पर गतिशील रूप से बदलती बाधाएं। ConstraintSet.apply यह काम नहीं किया, जब तक यह एक। इसलिए, onCreateViewHolder में माता-पिता को प्रचारित करें, लेकिन झूठी को भड़काने के लिए सशर्त परम के रूप में भेजें।
miroslavign

3
यह सही उपाय है! जैसा कि @Sniper ने कहा, दूसरे परम के लिए अशक्त होना बच्चे के दृश्य को खुद को संरेखित नहीं करने का कारण बन सकता है जैसा कि उसके माता-पिता को करना चाहिए। माता-पिता को पास करने वाले OTOH से प्रश्न में त्रुटि हो सकती है। तो, attachToRoot= असत्य, जाने का रास्ता है।
वासिलिस

इसे करने का सही तरीका।
रोलैंड माउंटेत्ज़ी

50

मैं अपने रिसाइकलव्यू के साथ त्रुटि खोजने पर यहाँ आया था, लेकिन समाधान काम नहीं किया (स्पष्ट रूप से)। मैंने recyclerview के मामले में इसका कारण और समाधान लिखा है। आशा है कि यह किसी की मदद करता है।

यदि onCreateViewHolder()निम्न विधि का अनुसरण किया जाता है , तो त्रुटि होती है :

layoutInflater = LayoutInflater.from(context);
return new VH(layoutInflater.inflate(R.layout.single_row, parent));

इसके बजाय यह होना चाहिए

return new VH(layoutInflater.inflate(R.layout.single_row, null));

15
कभी-कभी यादृच्छिक उत्तर जो कि पूछे गए प्रश्नों के उत्तर नहीं होते हैं, किसी और की मदद करते हैं। इसने मेरे लिए काम किया। धन्यवाद!
अजीथ मेमना

1
अच्छा !, और यही कारण है कि लोगों को ज्यादातर समय "अशक्त" को 2 डी मापदंडों के रूप में पारित करना चाहिए। धन्यवाद।
सुपरयूजर

4
माता-पिता के लिए जिम्मेदार पैरामीटर को अशक्त करना बुरा विचार नहीं है, लेकिन आपको यह जानना होगा कि इस मामले में बच्चे का दृष्टिकोण (जिसे आप फुलाते हैं) उसे कुछ मामलों में सही ढंग से स्वयं को मापने में सक्षम नहीं होगा, क्योंकि यह नहीं है जनक के बारे में कुछ भी जानना। कुछ मामलों में यह काम करेगा लेकिन कुछ में नहीं होगा।
स्टॉयचो एंड्रीव

1
ध्यान दें कि इससे दर्शकों का विषय सही तरीके से हल नहीं हो सकता है।
स्पेसबिसन

13

मुझे यह संदेश मिला है कि झूठ के बजाय जड़ से जुड़ने का उपयोग करके एक टुकड़ा करने की कोशिश करना, जैसे:

return inflater.inflate(R.layout.fragment_profile, container, true)

करने के बाद:

return inflater.inflate(R.layout.fragment_profile, container, false)

इसने काम कर दिया।


5

यदि अन्य समाधान की तरह काम नहीं कर रहा है:

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false);

आप किस खंड से लौट रहे हैं, इसकी जाँच करें कि क्या यह एकल दृश्य या दृश्यसमूह है? मेरे मामले में मेरे पास टुकड़े के xml की जड़ पर व्यूपेजर था और मैं व्यूपेजर को वापस कर रहा था, जब मैंने लेआउट में व्यूग्रुप जोड़ा तो मैंने अपडेट नहीं किया कि मुझे अब व्यूग्रुप (दृश्य) नहीं बल्कि व्यूग्रुप को वापस करना है।


5

frameLayout.addView (bannerAdView); <----- यदि आपको इस पंक्ति में त्रुटि मिलती है तो नीचे जैसा करें ..

if (bannerAdView.getParent() != null)

  ((ViewGroup) bannerAdView.getParent()).removeView(bannerAdView);

   frameLayout.addView(bannerAdView);     <------ now added view

4

मेरी त्रुटि इस तरह दृश्य को परिभाषित करती थी:

view = inflater.inflate(R.layout.qr_fragment, container);

यह गायब था:

view = inflater.inflate(R.layout.qr_fragment, container, false);

3

मेरे मामले में समस्या इस तथ्य के कारण थी कि मैं <merge>लेआउट के साथ माता-पिता के दृश्य को फुला रहा था । इस मामले में, addView()दुर्घटना का कारण बना।

View to_add = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, true);
// parent_layout.addView(to_add); // THIS CAUSED THE CRASH

हटाने addView()से समस्या को हल करने में मदद मिली।



2

नीचे दिए गए कोड ने इसे मेरे लिए हल कर दिया:

@Override
public void onDestroyView() {
    if (getView() != null) {
        ViewGroup parent = (ViewGroup) getView().getParent();
        parent.removeAllViews();
    }
    super.onDestroyView();
}

नोट: त्रुटि मेरे खंड वर्ग से थी और इस तरह onDestroy विधि को ओवरराइड करके, मैं इसे हल कर सकता था।



2

मेरे मामले में यह तब होता है जब मैं माता-पिता द्वारा अन्य दृश्य में दृश्य जोड़ना चाहता हूं

View root = inflater.inflate(R.layout.single, null);
LinearLayout lyt = root.findViewById(R.id.lytRoot);
lytAll.addView(lyt);  // ->  crash

आपको इस तरह से पैरेंट व्यू जोड़ना होगा

View root = inflater.inflate(R.layout.single, null);
LinearLayout lyt = root.findViewById(R.id.lytRoot);
lytAll.addView(root);

2

आपको सबसे पहले बच्चे के दृश्य को उसके माता-पिता से दूर करना होगा।

यदि आपकी परियोजना कोटलिन में है, तो आपका समाधान जावा की तुलना में थोड़ा अलग दिखेगा। कोटलिन ने कास्टिंग के साथ सरलीकरण किया है as?, यदि बाईं ओर अशक्त है तो नल वापस लौट रहा है या डाली विफल है।

(childView.parent as? ViewGroup)?.removeView(childView)
newParent.addView(childView)

कोटलिन एक्सटेंशन समाधान

यदि आपको इसे एक से अधिक बार करने की आवश्यकता है, तो अपने कोड को अधिक पठनीय बनाने के लिए इस एक्सटेंशन को जोड़ें।

childView.removeSelf()

fun View?.removeSelf() {
    this ?: return
    val parentView = parent as? ViewGroup ?: return
    parentView.removeView(this)
}

यदि यह दृश्य अशक्त है, तो यह सुरक्षित रूप से कुछ भी नहीं करेगा, अभिभावक दृश्य अशक्त है, या अभिभावक दृश्य व्यूग्रुप नहीं है


1

मुझे एक और ठीक लगा:

if (mView.getParent() == null) {
                    myDialog = new Dialog(MainActivity.this);
                    myDialog.setContentView(mView);
                    createAlgorithmDialog();
                } else {
                    createAlgorithmDialog();
                }

यहाँ मुझे सिर्फ एक if स्टेटमेंट चेक करना है अगर व्यू में पैरेंट था और अगर उसने नया डायलॉग नहीं बनाया था, तो कंटेंटव्यू सेट करें और मेरे "createAlgorithmDialog ()" विधि में डायलॉग दिखाएं।

यह भी सकारात्मक और नकारात्मक बटन (ओके और रद्द करें बटन) को onClickListeners के साथ सेट करता है।


0

आप इस मेथोड का उपयोग यह देखने के लिए कर सकते हैं कि कोई दृश्य बच्चों के लिए है या नहीं।

public static boolean hasChildren(ViewGroup viewGroup) {
    return viewGroup.getChildCount() > 0;
 }

0

मेरा मामला अलग था कि बच्चे का दृश्य पहले से ही एक माता-पिता का था, मैं माता-पिता के अंदर बच्चे के दृश्य को अलग-अलग माता-पिता से जोड़ रहा हूं। उदाहरण कोड नीचे

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/lineGap"
>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/black1"
    android:layout_gravity="center"
    android:gravity="center"
    />

</LinearLayout>

और मैं इस दृश्य को बढ़ा रहा था और एक अन्य लिनियरलाईट में जोड़ रहा था, फिर मैंने ऊपर के लेआउट से लिनरलैयूट को हटा दिया और इसका काम करना शुरू कर दिया

नीचे दिए गए कोड ने मुद्दा तय किया:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:gravity="center"
   android:textColor="@color/black1" />

0

मेरी समस्या कई अन्य उत्तरों से संबंधित है, लेकिन परिवर्तन करने की आवश्यकता के लिए थोड़ा अलग कारण ... मैं एक गतिविधि को एक परिमार्जन में बदलने की कोशिश कर रहा था। इसलिए मैंने onCreate से onCreateView में इनफ्लो कोड को स्थानांतरित कर दिया, लेकिन मैं setContentView से इनफ़्लो विधि में कनवर्ट करना भूल गया, और उसी IllegalStateException ने मुझे इस पृष्ठ पर लाया।

मैंने इसे बदल दिया:

binding = DataBindingUtil.setContentView(requireActivity(), R.layout.my_fragment)

इसके लिए:

binding = DataBindingUtil.inflate(inflater, R.layout.my_fragment, container, false)

इससे समस्या हल हो गई।

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