导航组件中的 IllegalStateException
IllegalStateException in NavigationComponent
我在我的应用程序中使用 Jetpack 的导航组件。我有 2 个片段,例如FirstFragment 和 SecondFragment 以及我在导航图中从第一个到第二个都有导航。一切都以这种方式正常工作。我想将子片段添加到 FirstFragment。所以在 FirstFragment class 的 onCreateView 方法中,我添加了行
getChildFragmentManager().beginTransaction().add(R.id.fragment_container, new SimpleFragment()).commit();
这样我在 FirstFragment 中就有了一个内部片段。从 FirstFragment 导航到 SecondFragment 仍然可以正常工作,但是当我在 SecondFragment 中按下后退按钮时,出现此错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abc.def, PID: 28856
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:4937)
at android.view.ViewGroup.addView(ViewGroup.java:4768)
at android.view.ViewGroup.addView(ViewGroup.java:4708)
at android.view.ViewGroup.addView(ViewGroup.java:4681)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1353)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1642)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1736)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1800)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3096)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3050)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2688)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1369)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2633)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2377)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2333)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2230)
at androidx.fragment.app.FragmentManager.run(FragmentManager.java:414)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
如果我按后退按钮或调用 navController.navigateUp()
或 navController.popBackStack()
,我会收到此错误。如果我删除行
getChildFragmentManager().beginTransaction().add(R.id.fragment_container, new SimpleFragment()).commit();
from FirstFragment 我没有错误,所以这意味着子片段管理器有问题,对吧?这里有什么问题?
如果我在不知道你有什么的情况下正确理解这一点,而不看你的“fragment_container
”布局告诉我它的 ViewGroup
类型只能有一个 child 在如果您不向它提供更多信息,请注意这一点。
这意味着 fragment_container
已经有一个 child,您需要在添加 SimpleFragment
之前将其删除。
假设您的第一个片段布局类似于这样
<someView>
<fragment_container/> // hear you are loading your first fragment and trying load the SimpleFragment as well which is causing problem.
</someView>
你需要的是
<someView>
<fragment_container/> only load First Fragment "first_fragment_layout.xml"
</someView>
并且在第一个片段的布局中
first_fragment_layout.xml
<someView>
<viewBlasBla/>
<viewBlasBla/>
<fragment_container/> load SimpleFragment here
</someView>
如您所见,您确实在尝试嵌套片段,这不是一个好的做法。尽可能避免这种情况:).
问题出在 SimpleFragment 中。我一直在引用该片段的根视图(有 View mRootView
字段),并且没有重新创建它以防它不为空。
我在我的应用程序中使用 Jetpack 的导航组件。我有 2 个片段,例如FirstFragment 和 SecondFragment 以及我在导航图中从第一个到第二个都有导航。一切都以这种方式正常工作。我想将子片段添加到 FirstFragment。所以在 FirstFragment class 的 onCreateView 方法中,我添加了行
getChildFragmentManager().beginTransaction().add(R.id.fragment_container, new SimpleFragment()).commit();
这样我在 FirstFragment 中就有了一个内部片段。从 FirstFragment 导航到 SecondFragment 仍然可以正常工作,但是当我在 SecondFragment 中按下后退按钮时,出现此错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abc.def, PID: 28856
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:4937)
at android.view.ViewGroup.addView(ViewGroup.java:4768)
at android.view.ViewGroup.addView(ViewGroup.java:4708)
at android.view.ViewGroup.addView(ViewGroup.java:4681)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1353)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1642)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1736)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1800)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3096)
at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3050)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2688)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1369)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2633)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2377)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2333)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2230)
at androidx.fragment.app.FragmentManager.run(FragmentManager.java:414)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
如果我按后退按钮或调用 navController.navigateUp()
或 navController.popBackStack()
,我会收到此错误。如果我删除行
getChildFragmentManager().beginTransaction().add(R.id.fragment_container, new SimpleFragment()).commit();
from FirstFragment 我没有错误,所以这意味着子片段管理器有问题,对吧?这里有什么问题?
如果我在不知道你有什么的情况下正确理解这一点,而不看你的“fragment_container
”布局告诉我它的 ViewGroup
类型只能有一个 child 在如果您不向它提供更多信息,请注意这一点。
这意味着 fragment_container
已经有一个 child,您需要在添加 SimpleFragment
之前将其删除。
假设您的第一个片段布局类似于这样
<someView>
<fragment_container/> // hear you are loading your first fragment and trying load the SimpleFragment as well which is causing problem.
</someView>
你需要的是
<someView>
<fragment_container/> only load First Fragment "first_fragment_layout.xml"
</someView>
并且在第一个片段的布局中
first_fragment_layout.xml
<someView>
<viewBlasBla/>
<viewBlasBla/>
<fragment_container/> load SimpleFragment here
</someView>
如您所见,您确实在尝试嵌套片段,这不是一个好的做法。尽可能避免这种情况:).
问题出在 SimpleFragment 中。我一直在引用该片段的根视图(有 View mRootView
字段),并且没有重新创建它以防它不为空。