बच्चे के माता-पिता पर पहले कॉल हटाएं ()


138

पहले थोड़ा बैकग्राउंड:

मेरे पास एक स्क्रॉलव्यू के अंदर एक लेआउट है। सबसे पहले, जब उपयोगकर्ता स्क्रीन पर स्क्रॉल करता है, तो स्क्रॉलव्यू स्क्रॉल करता है। हालाँकि, एक निश्चित मात्रा में स्क्रॉल करने के बाद, मुझे स्क्रॉल पर स्क्रॉल को अक्षम करना था कि "लेआउट फ़ोकस" को बाल लेआउट के अंदर एक वेबव्यू पर ले जाएं। इस तरह, स्क्रोलव्यू चिपक जाता है और सभी स्क्रॉल इवेंट इसके अंदर वेबव्यू पर चले जाते हैं।

इसलिए, एक समाधान के लिए, जब स्क्रॉल थ्रेशोल्ड पहुंच जाता है, तो मैं स्क्रॉलव्यू से चाइल्ड लेआउट को हटा देता हूं और इसे स्क्रॉलव्यू के माता-पिता में डाल देता हूं। (और स्क्रॉलव्यू को अदृश्य बना देता हूं)।

// Remove the child view from the scroll view
scrollView.removeView(scrollChildLayout);

// Get scroll view out of the way
scrollView.setVisibility(View.GONE);

// Put the child view into scrollview's parent view
parentLayout.addView(scrollChildLayout);

सामान्य विचार: (-> का अर्थ है)

इससे पहले: पेरेंटेलआउट -> स्क्रॉलव्यू -> स्क्रॉलचिल्डआउट

के बाद: parentLayout -> स्क्रॉलचिल्डआउट

उपरोक्त कोड मुझे यह अपवाद दे रहा है:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
           at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
           at android.view.ViewGroup.addView(ViewGroup.java:1871)
           at android.view.ViewGroup.addView(ViewGroup.java:1828)
           at android.view.ViewGroup.addView(ViewGroup.java:1808)

क्या आप जानते हैं कि क्या हो रहा है? मैं माता-पिता को स्पष्ट रूप से हटाने वाला दृश्य कह रहा हूं।

जवाबों:


289

उपाय:

((ViewGroup)scrollChildLayout.getParent()).removeView(scrollChildLayout);
//scrollView.removeView(scrollChildLayout);

माता-पिता का संदर्भ पाने के लिए बच्चे के तत्व का उपयोग करें। माता-पिता को एक व्यूग्रुप में कास्ट करें ताकि आप रिमूव व्यू पद्धति तक पहुंच सकें और इसका उपयोग कर सकें।

समाधान के लिए @Dongshengcn को धन्यवाद


1
समाधान सही है, लेकिन क्यों "scollView.removeView (ScrollChildLayout)" काम नहीं करेगा? क्या दो रेखाएँ समान नहीं होनी चाहिए?
andrea.rinaldi

@ andrea.spot, ऐसा लगता है कि स्क्रॉलव्यू scrollView.removeView(scrollChildLayout)के बच्चे को हटाने की कोशिश की जा रही है, स्क्रॉलव्यू को खुद उसके अभिभावक
व्यूग्रुप

1
@ user25 मुझे यह पता है कि शायद यू के लिए बहुत देर हो चुकी है, लेकिन अशक्त सूचक अपवाद माता-पिता के खाली होने के कारण है, यह दृश्य किसी भी माता-पिता से जुड़ा नहीं है। चूँकि शुरुआत में कोई माता-पिता नहीं है, इसलिए कुछ भी नहीं है if (mAdView.getParent()!=null) ((ViewGroup) mAdView.getParent()).removeView(mAdView);
तारेक

@kasgoku कृपया आप मेरी मदद कर सकते हैं। मैं एक बटन क्लिक पर रिश्तेदार लेआउट में एक टुकड़ा दिखाने की कोशिश कर रहा हूँ। लेकिन इसकी त्रुटि दिखाते हुए "निर्दिष्ट बच्चे के पास पहले से ही एक माता-पिता हैं। आपको पहले बच्चे के माता-पिता पर हटाने के दृश्य () को कॉल करना होगा।" इसे कैसे हल किया जाए?
इमराना ०

मुझे यह त्रुटि मेरे एप्लिकेशन में भी मिली जो चैट एप्लिकेशन में से एक है। मैं इस समस्या को हल करने की कोशिश कर रहा हूं। उस आइकन को हटा दिया गया है लेकिन मुझे छवियों को अपलोड करने के लिए फिर से आइकन की आवश्यकता है। ( stackoverflow.com/q/58117428/10971384 ) यह मेरा प्रश्न लिंक है
थांगपंडी

21

पहली बार अपने मूल दृश्य से स्क्रॉलचाइल्डआउट को हटाने का प्रयास करें?

scrollview.removeView(scrollChildLayout)

या माता-पिता के दृष्टिकोण से सभी बच्चे को हटा दें, और उन्हें फिर से जोड़ें।

scrollview.removeAllViews()

मैं ऊपर दिए गए अपने प्रश्न में कोड में पहले से ही हटाने वाला कह रहा हूं। removeAllViews () या तो काम नहीं करता है।
कासगोकु

क्या आप सुनिश्चित हैं कि यह वह माता-पिता है, जिसे आप removeView () / removeAllViews () कह रहे हैं? मैं बहुत समान काम कर रहा हूं, और यह मेरे लिए काम कर रहा है।
dongshengcn

4
आप इसके अभिभावक को देख कर देख सकते हैं: view.getParent () developer.android.com/reference/android/view/…
dongshengcn

@dongshengcn कृपया आप मेरी मदद कर सकते हैं। मैं एक बटन क्लिक पर रिश्तेदार लेआउट में एक टुकड़ा दिखाने की कोशिश कर रहा हूँ। लेकिन इसकी त्रुटि दिखाते हुए "निर्दिष्ट बच्चे के पास पहले से ही एक माता-पिता हैं। आपको पहले बच्चे के माता-पिता पर हटाने के दृश्य () को कॉल करना होगा।" इसे कैसे हल किया जाए?
इमराना ०

19

गतिविधि के साथ onCreate में या टुकड़े के साथ onCreateView में।

 if (view != null) {
    ViewGroup parent = (ViewGroup) view.getParent();
    if (parent != null) {
        parent.removeView(view);
    }
}
try {
    view = inflater.inflate(R.layout.fragment_main, container, false);
} catch (InflateException e) {

}

15

ठीक है, मुझे पागल कहो लेकिन मेरा सुझाव है:

  final android.view.ViewParent parent = view.getParent ();

  if (parent instanceof android.view.ViewManager)
  {
     final android.view.ViewManager viewManager = (android.view.ViewManager) parent;

     viewManager.removeView (view);
  } // if

बिना कास्टिंग instanceof सिर्फ गलत लगता है। और (मुझे बताने के लिए IntelliJ IDEA) इंटरफ़ेस removeViewका हिस्सा है ViewManager। और जब पूरी तरह से उपयुक्त इंटरफ़ेस उपलब्ध होता है, तो किसी को ठोस वर्ग में नहीं जाना चाहिए।


3

आपको बस इतना करना है कि addView () एक रन करने योग्य पोस्ट है।


काम नहीं किया। यह वही है जो मैंने कोशिश की थी: scrollView.removeView (ScrollChildLayout); scrollView.setVisibility (View.GONE); parentLayout.post (नया Runnable () {@Override public void run () {parentLayout.addView (ScrollChildLayout);}});
कासगोकु

1

मैं parentView.removeView (childView) को कॉल कर रहा था और चाइल्ड व्यू अभी भी दिखा रहा था। मुझे अंततः एहसास हुआ कि एक विधि को किसी तरह दो बार ट्रिगर किया जा रहा था और चाइल्ड व्यू को दो बार पैरेंट व्यू में जोड़ा गया।

इसलिए, यह देखने के लिए कि आपके द्वारा पहले और बाद में माता-पिता के कितने बच्चे हैं, यह निर्धारित करने के लिए parentView.getChildCount () का उपयोग करें। यदि बच्चे को कई बार जोड़ा जाता है तो शीर्ष सबसे अधिक बच्चे को हटाया जा रहा है और कॉपी चाइल्ड व्यू बनी हुई है-जो दिखता है कि हटाए जाने पर भी यह काम कर रहा है।

इसके अलावा, आपको किसी दृश्य को हटाने के लिए View.GONE का उपयोग नहीं करना चाहिए। यदि यह वास्तव में हटा दिया गया है तो आपको इसे छिपाने की आवश्यकता नहीं होगी, अन्यथा यह अभी भी है और आप इसे स्वयं से छिपा रहे हैं :(


1

मेरे मामले में, मेरे पास बेसग्रैगमेंट है और अन्य सभी टुकड़े इसी से विरासत में मिले हैं।

इसलिए मेरा आग्रह OnDestroyView()विधि में इस पंक्तियों को जोड़ना था

@Override
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    if (mRootView == null)
    {
        mRootView = (inflater == null ? getActivity().getLayoutInflater() : inflater).inflate(mContentViewResourceId, container, false);
    }
....////
}

@Override
public void onDestroyView()
{
    if (mRootView != null)
    {
        ViewGroup parentViewGroup = (ViewGroup) mRootView.getParent();

        if (parentViewGroup != null)
        {
            parentViewGroup.removeAllViews();
        }
    }

    super.onDestroyView();
}

क्या आपने अगला टुकड़ा चुनने का प्रयास किया है और बहुत तेजी से वापस दबाया है?
17मथ्वॉएड

1

कोटलिन समाधान

कोटलिन माता-पिता की कास्टिंग को सरल बनाता है as?, अगर पीछे की तरफ अशक्त है या वापस आ रहा है तो अशक्त हो जाता है।

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

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

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

childView.removeSelf()

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

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

नोट: यदि आप भी माता-पिता द्वारा बच्चे के विचारों को सुरक्षित निकालना चाहते हैं, तो इसे जोड़ें:

fun ViewGroup.removeViewSafe(toRemove: View) {
    if (contains(toRemove)) removeView(toRemove)
}

0

आप यह भी देख सकते हैं कि यदि IndexOfView विधि -1 लौटाता है तो View's indexOfView विधि देखें।

ViewGroup का detachViewFromParent (v); व्यूग्रुप के निष्कासन दृश्य के बाद (v, सत्य / असत्य);


0

मैं गलत कर रहा था, इसलिए मुझे यह त्रुटि मिली कि मैं गतिशील लेआउट को त्वरित नहीं कर रहा था और इसमें चिल्ड जोड़ रहा था इसलिए यह त्रुटि मिली


0

यहाँ मेरा समाधान है।

कहते हैं कि आपके पास दो हैं TextViewsऔर उन्हें एक LinearLayout(नाम ll) पर रखा गया है । आप इसे LinerLayoutदूसरे पर डालेंगे LinerLayout

< lm Linear Layout> 
       < ll Linear Layout> 
             <name Text view>
             </name Text view>
             <surname Text view>
             </surname Text view>
       </ll Linear Layout> 
</lm Linear Layout> 

जब आप इस संरचना को बनाना चाहते हैं तो आपको माता-पिता को विरासत के रूप में देने की आवश्यकता होती है।

आप चाहे तो इसे एक onCreateविधि में इस्तेमाल कर सकते हैंthis पर्याप्त होगा।

नहीं तो यहाँ है विलाप:

LinerLayout lm = new LinearLayout(this); // You can use getApplicationContext() also
LinerLayout ll = new LinearLayout(lm.getContext());
TextView name = new TextView(ll.getContext());
TextView surname = new TextView(ll.getContext());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.