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.