java.lang.IllegalStateException: Belirtilen alt öğenin zaten bir ebeveyni var


99

Bir parçayı ilk kez somutlaştırdığımda parçalar kullanıyorum. ama ikinci kez bu istisnayı aldım. Hatayı aldığım satırı bulamadım?

 04-04 08:51:54.320: E/AndroidRuntime(29713): FATAL EXCEPTION: main
    04-04 08:51:54.320: E/AndroidRuntime(29713): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addViewInner(ViewGroup.java:3013)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2902)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2859)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2839)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.NoSaveStateFrameLayout.wrap(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.BackStackRecord.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl$1.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Handler.handleCallback(Handler.java:587)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Handler.dispatchMessage(Handler.java:92)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Looper.loop(Looper.java:132)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.app.ActivityThread.main(ActivityThread.java:4126)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at java.lang.reflect.Method.invokeNative(Native Method)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at java.lang.reflect.Method.invoke(Method.java:491)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at dalvik.system.NativeStart.main(Native Method)

İşte liste parçamın bir öğesine tıkladığımda yaptığım şey.

// If we are not currently showing a fragment for the new
 // position, we need to create and install a new one.
 RouteSearchFragment df = RouteSearchFragment.newInstance(index);

 // Execute a transaction, replacing any existing fragment
 // with this one inside the frame.
 FragmentTransaction ft = fragmentManager.beginTransaction();
 ft.replace(R.id.details_full, df);
 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
 ft.commit();

Tamam olduğunda ilk kez listeden element2'yi tıklıyorum, bu da tamam; ancak element1'e döndüğümde bu hatayı aldım.

Herkese teşekkürler!


layoutView.removeAllViews () öğesini çağırmanız gerekir; yerleşim düzenine görünüm eklemeden önce
ρяσѕρєя K

@imrankhan yanlış! Tümünü kaldırmadan ekleyebilirsiniz. En önemli kısım eksik ve
yığın izlemede

1
daha fazla ayrıntı ekledim, lütfen bunu görüyor musun?
haythem souissi

Bu RouteSearchFragment sınıfı nedir? Android dokümanlarında herhangi bir referans bulunamıyor. Lütfen sınıf tanımını da güncelleyin.
noob

Yanıtlar:


36

Eğer geçersiz zaman OnCreateViewsizin de RouteSearchFragmentsınıfta söz konusu mu

if(view != null) {
    return view; 
}

kod bölümü?

Eğer öyleyse, return ifadesini kaldırmak sorununuzu çözmelidir.

Görünüm verilerini yeniden oluşturmak istemiyorsanız kodu saklayabilir ve görünümü geri döndürebilirsiniz ve onDestroyView () yöntemi bu görünümü üst öğesinden şu şekilde kaldırırsınız:

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

5
@Override public void onDestroyView () {super.onDestroyView (); ViewGroup parentViewGroup = (ViewGroup) mRoutesSearchViewContainer.getParent (); if (null! = parentViewGroup) {parentViewGroup.removeView (mRoutesSearchViewContainer); }}
haythem souissi

@Medo: Bunun için kısa bir açıklama yapabilir misiniz? Logcat'ta gösterilen aynı hatayı görüyorum. "return deyimini kaldır, sorununuzu çözmelidir" önerisini verdiğiniz gibi, ancak onCreateView () yönteminde View nesnesini döndürmemiz gerekiyor. açıklamanız için pasaj kodu sağlayabilir misiniz? Teşekkür ederim.
Krishna Prasad

@Krishna Normalde yaptığınız gibi görünümü şişirin ve döndürün. Tüm if ifadesini atlayabilirsiniz.
Medo

65
Benim için, sadece değiştirmek zorunda return inflater.inflate(R.layout.fragment_search, container);olanreturn inflater.inflate(R.layout.fragment_search, container, false);
Süfyan

370

Eski bir soruya gönderdiğim için üzgünüm ama tamamen farklı bir çözüm kullanarak sorunu çözebildim. Bu istisnayı alıyordum ama onCreatView geçersiz kılmamın ilk satırını bundan değiştirdim:

View result = inflater.inflate(R.layout.customer_layout, container);

...buna:

View result = inflater.inflate(R.layout.customer_layout, container, false);

Üçüncü parametre olarak boole'yi kabul eden geçersiz kılmanın neden düzeltildiğine dair hiçbir fikrim yok. Sanırım Parça ve / veya Aktiviteye "kapsayıcı" yı yeni oluşturulan Görünümün üst öğesi olarak kullanmamasını söylüyor.


53
Üzülme - bu benim için çok faydalı oldu ve belli ki birçok insan. Teşekkürler!
kodlarını girin

Çok teşekkürler, bunu
unutup

@Patrick, İlki şişirilmiş görünümü konteynere iliştirir, yanlış bayrak ekleyerek şişirilmiş görünümü konteynere eklemek istemediğinizi belirtir.
Ne0

ve bu
gönderiye

45

Bu sorunla birçok kez karşılaştım. Bu sorunu çözmek için lütfen aşağıdaki kodu ekleyin:

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

Teşekkürler


Bu çözüm için teşekkür ederim :) Bunu çözmek için şişirici kullanamayacağım çok özel bir durumum var. Bana çok zaman kazandırdın
Bojan

Üzgünüm, tam olarak anlamıyorum çünkü android'de yeniyim.
Zin Win Htet

View.getParent () içinde; Doz görünümü nesnesi nereden geliyor?
Zin Win Htet

Cristy YG: Global değişken olarak bir View örneğini alın ve mizanpaj xml'nizi yukarıdaki global değişken üzerinde şişirin. beni takip ediyor musun değil mi
Hardik

Evet, görünüm örneği genel olarak bildirilir.
Hardik

35

Bu ifadeye sahipseniz ..

View view = inflater.inflate(R.layout.fragment1, container);//may be Incorrect 

Sonra şunu deneyin .. Üçüncü argüman olarak yanlış ekleyin .. Yardımcı olabilir ..

View view = inflater.inflate(R.layout.fragment1, container, false);//correct one

21

Bu kodu bir parçada tuttum ve bu parçaya geri dönmeye çalışırsam çöküyordu

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} 

Bu konudaki cevapları topladıktan sonra, mRootView ebeveyninin hala çocuk olarak mRootView olduğunu fark ettim. Yani, bu benim fikrimdi.

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} else {
    ((ViewGroup) mRootView.getParent()).removeView(mRootView);
}

Bu yardımcı olur umarım


2
+1 bana yardımcı oldu. Özellikle etkinliğiniz devam ederse, ancak parça yöneticisi üstüne yeni parçalar ekliyorsa geçerlidir. ilk parçaya geri döndüğünde, eski kök görünümünün kaldırıldığından emin olmanız gerekir. Teşekkürler!
Bundeeteddee

Bana çok yardımcı oldu. 3 gündür bu çözümü buluyorum. Basit ve güzel cevap.
Zin Win Htet

Vaov! sonunda benim için çalıştı! grat çözüm. Teşekkürler!
avisper

Neden "(ViewGroup) mRootView.getParent ()). RemoveView (mRootView);" için bir gerekçem yok doğrudan "<WhateverIsParentViewGroupName> .removeView (mRootView)" çağırmanın aksine çalışır Ancak bu benim için de işe yarıyor, Android 8.0 ve 9.0'da test ediyorum. Teşekkürler bud ^
Khay

16

Ayrıca onCreateView () tarafından döndürülen görünüm şişirilmiş görünüm olmadığında da olur.

Misal:

View rootView = inflater.inflate(R.layout.my_fragment, container, false);

TextView textView = (TextView) rootView.findViewById(R.id.text_view);
textView.setText("Some text.");

return textView;

Düzeltme:

return rootView;

Onun yerine:

return textView; // or whatever you returned

Teşekkürler! Bana yardımcı oldu!
Sudheesh Mohan

5

Bu sorunu yaşadım ve Java kodunda çözemedim. Sorun xml'imle ilgiliydi.

Bir kapsayıcıya bir textView eklemeye çalışıyordum, ancak textView'ı bir LinearLayout içine sarmalamıştım.

Bu orijinal xml dosyasıydı:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#fff"
        android:background="?android:attr/activatedBackgroundIndicator"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

</LinearLayout>

Şimdi LinearLayout kaldırıldığında:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#fff"
        android:background="?android:attr/activatedBackgroundIndicator"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

Bu bana pek bir şey gibi gelmedi ama işe yaradı ve Java kodumu hiç değiştirmedim. Hepsi xml içindeydi.


2

Bir ekliyoruz Viewbir içine layout, ancak Görünüm zaten başka içindedir layout. Bir Görünüm birden fazla yerde olamaz.


soruma daha fazla ayrıntı ekledim, lütfen bunu görüyor musun?
haythem souissi

1

Bu çözüm yardımcı olabilir:

public class FragmentItem extends Android.Support.V4.App.Fragment
{
    View rootView;
    TextView textView;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (rootView != null) 
        {
            ViewGroup parent = (ViewGroup)rootView.Parent;
            parent.RemoveView(rootView);
        } else {
            rootView = inflater.Inflate(Resource.Layout.FragmentItem, container, false);
            textView = rootView.FindViewById<TextView>(Resource.Id.textViewDisplay);            
        }
        return rootView;
    }
}

1
Bence rootView, siz onu başlatmadığınız için her zaman boş olacaktır.
Zin Win Htet

rootView her zaman boş
Thinsky

1

Ben ayarlayarak bunu çözmüş attachToRootarasında inflater.inflate()hiç false.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_overview, container, false);
    return view;
}

0

xml dosyanızda layout_width ve layout_height'ı wrap_content'den match_parent'a ayarlamalısınız. benim için düzeltildi.

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.