java.lang.IllegalStateException: У вказаної дитини вже є батько


99

Я використовую фрагменти, коли інстанціюю фрагмент вперше його. але вдруге я отримав цей виняток. Не вдалося знайти рядок, де я отримав помилку?

 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)

Ось що я роблю, коли натискаю на елемент фрагмента мого списку.

// 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();

Перший раз це Ok, я клацаю element2 зі списку, це також нормально; але коли я повернусь до елемента1, я отримав цю помилку.

Дякую всім!


потрібно викликати layoutView.removeAllViews (); перед тим, як додати перегляди до верстки
ρяσѕρєя K

@imrankhan неправильно! Ви можете додати, не видаляючи всіх. Найважливіша частина відсутня, і оскільки в стек-тракті немає спеціального пакету, я пропоную вам видалити код і перевірити його поетапно ...
WarrenFaith

1
я додаю більше деталей, будь ласка, ви можете це бачити?
haythem souissi

Що це за клас RouteSearchFragment ?? Не вдається знайти жодних посилань у документах Android. Оновіть також визначення класу.
noob

Відповіді:


36

Коли ви перекриваєте OnCreateViewсвій RouteSearchFragmentклас, чи маєте ви це?

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

сегмент коду?

Якщо так, видалення заяви про повернення повинно вирішити вашу проблему.

Ви можете зберегти код і повернути вигляд, якщо ви не хочете регенерувати дані перегляду, а методом onDestroyView () ви видалите цей погляд з його батьківського типу так:

    @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: Ви можете дати коротке пояснення цьому. У мене така ж помилка показана в logcat. як ви дали пропозицію "видалити оператор return повинен вирішити вашу проблему", але нам потрібно повернути об'єкт View у методі onCreateView (). чи можете ви надати фрагмент коду для пояснення. Дякую.
Крішна Прасад

@Krishna Просто надуйте та поверніть вигляд, як зазвичай. Ви можете пропустити ціле if оператор.
Медо

65
Для мене, я просто повинен був замінити return inflater.inflate(R.layout.fragment_search, container);зreturn inflater.inflate(R.layout.fragment_search, container, false);
Суфьян

370

Вибачте за повідомлення про старе питання, але мені вдалося виправити це за допомогою зовсім іншого рішення. Я отримував цей виняток, але я змінив перший рядок свого перегляду на onCreatView від цього:

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

...до цього:

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

Я поняття не маю, чому, окрім використання переопределення, яке сприймає булеве значення, як це зафіксував третій парам. Я думаю, що це говорить Фрагмент та / або Діяльність не використовувати "контейнер" як батьківство новоствореного перегляду.


53
Не шкодуйте - це було дуже корисно і мені, і, очевидно, низці інших людей. Дякую!
голова в кодах

Велике спасибі, я продовжую це забувати і повертаюся до цієї відповіді
noloman

@Patrick, Перший додає до контейнера завищений вигляд, додаючи помилковий прапор, ви вказуєте, що ви не хочете додати надутий вигляд до контейнера.
Ne0

і я продовжую повертатися до цієї публікації і з’ясовую, що це ВІДПОВІДЬ :)
noloman

45

Я стикався з цим питанням багато разів. Для вирішення цієї проблеми додайте наступний код:

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

Дякую


Дякую за це рішення :) У мене є дуже специфічний випадок, коли я не можу використовувати надувні для вирішення цього питання. Ви врятували мені багато часу
Божан

Вибачте, я не зовсім розумію, бо я новачок в android.
Zin Win Htet

In view.getParent (); Звідки береться об'єкт перегляду дози?
Zin Win Htet

Cristy YG: Візьміть екземпляр View як глобальну змінну та надуйте ваш макет xml на вище глобальну змінну. ти слідкуєш за мною чи ні?
Хардік

Так, перегляд екземпляра оголосити глобальним.
Хардік

35

Якщо у вас є це твердження ..

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

Потім спробуйте це. Додайте помилку як третій аргумент. Можливо, це може допомогти ..

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

21

У мене був цей фрагмент у фрагменті, і він розбився, якщо я спробую повернутися до цього фрагмента

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

зібравши відповіді на цій темі, я зрозумів, що батько mRootView все ще має mRootView як дочірню. Отже, це було моє виправлення.

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

сподіваюся, що це допомагає


2
+1 допомогло мені. Особливо вірно, якщо ваша діяльність залишається, але менеджер фрагментів додає нові фрагменти зверху. коли він повертається до першого фрагмента, потрібно переконатися, що старий вигляд кореня видаляється. Дякую!
Bundeeteddee

Це мені дуже допомогло. Я знайшов це рішення вже 3 дні. Проста і симпатична відповідь.
Zin Win Htet

Оце Так! нарешті це працювало для мене! грати рішення. Дякую!
avisper

У мене немає обґрунтування того, чому "(ViewGroup) mRootView.getParent ()). RemoveView (mRootView);" працює на відміну від прямого виклику "<WeverIsParentViewGroupName> .removeView (mRootView)", але це працює і для мене, я тестую на Android 8.0 і 9.0. Дякую буд ^
Хай

16

Це також трапляється, коли подання, повернене onCreateView (), не є передумом перегляду.

Приклад:

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;

Виправити:

return rootView;

Замість:

return textView; // or whatever you returned

Дякую! це мені допомогло!
Sudheesh Mohan

5

У мене була ця проблема і не вдалося її вирішити в коді Java. Проблема була в моєму xml.

Я намагався додати textView до контейнера, але загорнув textView всередині LinearLayout.

Це був оригінальний файл xml:

<?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>

Тепер із вилученим LinearLayout:

<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"/>

Мені це здалося не дуже схожим, але це зробило трюк, і я зовсім не змінив свій код Java. Це все було в xml.


2

Ви додаєте Viewв layout, але перегляд вже є в іншому layout. Перегляд не може містити більше ніж одне місце.


я додав більше деталей до мого запитання, будь ласка, ви можете це бачити?
haythem souissi

1

Це рішення може допомогти:

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
Я думаю, що rootView завжди буде нульовим, оскільки ви не ініціалізували його.
Zin Win Htet

rootView завжди буде нульовим
Thinsky

1

Я вирішив його, встановивши attachToRootв inflater.inflate()до false.

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

0

у вашому XML-файлі слід встановити layout_width та layout_height від wrap_content до match_parent. це для мене виправлено.

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.