java.lang.IllegalStateException:指定された子にはすでに親があります


99

フラグメントを初めて使用するときにフラグメントを使用しています。2回目はこの例外が発生しました。エラーが発生した行が見つかりませんでしたか?

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

初めての場合は、リストからelement2をクリックします。これも問題ありません。しかし、element1に戻ると、このバグが発生しました。

みんな、ありがとう!


layoutView.removeAllViews();を呼び出す必要があります。レイアウトに追加ビューの前に
ρяσѕρєяK

@imrankhan間違い!すべて削除せずに追加できます。最も重要な部分が欠落しており、スタックトレースにカスタムパッケージがないため、コードをいくつか削除して、段階的にテストすることをお勧めします...
WarrenFaith

1
詳細を追加します。ご覧いただけますか?
haythem souissi 2012

このRouteSearchFragmentクラスは何ですか?Androidドキュメントに参照が見つかりません。クラス定義も更新してください。
noob

回答:


36

クラスでオーバーライドOnCreateViewするときRouteSearchFragment、あなたは持っていますか

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

コードセグメント?

その場合、returnステートメントを削除すると問題が解決するはずです。

ビューデータを再生成したくない場合は、コードを保持してビューを返すことができます。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 2012

@メド:これについて簡単に説明してください。logcatに同じエラーが表示されます。「returnステートメントを削除すると問題が解決するはずです」という提案をしたので、onCreateView()メソッドでViewオブジェクトを返す必要があります。説明のためにスニペットコードを提供できますか。ありがとうございました。
クリシュナプラサード

@クリシュナ通常どおり、ビューを膨張させて返します。ifステートメント全体をスキップできます。
Medo 2013

65
私にとって、私は次のものと交換return inflater.inflate(R.layout.fragment_search, container);しなければなりませんでしたreturn inflater.inflate(R.layout.fragment_search, container, false);
Sufian

370

古い質問に投稿して申し訳ありませんが、まったく異なるソリューションを使用して修正することができました。この例外が発生しましたが、onCreatViewオーバーライドの最初の行を次のように変更しました。

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

...これに:

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

理由はわかりませんが、3番目のパラメーターとしてブール値を受け入れるオーバーライドを使用して修正しました。フラグメントやアクティビティに、「コンテナ」を新しく作成したビューの親として使用しないように指示していると思います。


53
申し訳ありませんが、これは私にとって、そして他の多くの人々にとって非常に有用でした。ありがとう!
コード


@Patrick、最初にインフレートされたビューをコンテナにアタッチし、falseフラグを追加して、インフレートされたビューをコンテナに追加しないことを指定します。
Ne0

そして私はこの投稿に戻ってきて、これが「答え」であることを発見し続けます:)
noloman

45

私はこの問題に何度も直面しています。この問題を解決するには、次のコードを追加してください:

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

ありがとう


この解決策に感謝します:)これを解決するためにインフレーターを使用できない非常に特殊なケースがあります。あなたは多くの時間を節約してくれました
Bojan

申し訳ありませんが、Androidを初めて使用するのはよくわかりません。
Zin Win Htet 2014

view.getParent(); 線量ビューオブジェクトはどこから来ますか?
Zin Win Htet 2014

Cristy YG:Viewインスタンスをグローバル変数として受け取り、上記のグローバル変数でレイアウトxmlを膨らませます。あなたは私をフォローしていますか?
Hardik、2014

はい、ビューインスタンスはグローバルとして宣言されています。
Hardik、2015年

35

このステートメントがある場合。

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

次に、これを試してください。3番目の引数としてfalseを追加してください。

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 2013年

それは私を大いに助けました。私はその解決策を3日間探し続けています。シンプルでかなりの答え。
Zin Win Htet 2014

うわー!ついにそれは私のために働きました!gratソリューション。ありがとう!
avisper 2017

「(ViewGroup)mRootView.getParent())。removeView(mRootView);」という理由はありません。「<WhateverIsParentViewGroupName> .removeView(mRootView)」を直接呼び出すのとは対照的に機能しますが、これは私にとっても機能します。Android8.0および9.0でテストしています。ありがとうバッド^
2019

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 2015

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

にを追加しViewlayoutいますが、ビューはすでに別のにありlayoutます。ビューを複数の場所に配置することはできません。


質問に詳細を追加しました。それをご覧いただけますか?
haythem souissi 2012

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は常にnullになると思います。
Zin Win Htet 2014

rootViewは常にnullである
Thinsky、2015年

1

toの設定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" />
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.