android - 卡在替换片段
问题描述
我有一个底部导航视图,当我单击下面的 tabitem 时,我想替换两个片段。
fun onCreate() {
replaceFragment(FragmentFirst())
replaceFragment(FragmentSecond())
replaceFragment(FragmentFirst())
replaceFragment(FragmentSecond())
replaceFragment(FragmentFirst())
}
如果 supportmanager 没有找到片段,则替换并添加到 backstack,如果 supportmanager 有片段,则仅替换现有片段,如下所示。
fun replaceFragment(fragment: Fragment, addToBackStack: Boolean) {
val transaction = supportFragmentManager.beginTransaction()
val fragmentFromStack = supportFragmentManager.findFragmentByTag(fragment.javaClass.toString())
if (fragmentFromStack == null) {
transaction.replace(R.id.container, fragment, fragment.javaClass.toString())
transaction.addToBackStack(null)
} else {
transaction.replace(R.id.container, fragmentFromStack)
}
transaction.commit()
}
问题是当我在 FragmentFirst() 打开时单击返回按钮时发生异常。
IllegalStateException:已在 tabhost 片段中添加了片段
我不明白什么时候出现问题。是否有任何解决方案或替代方法可以像这样导航。
2020-02-27 13:39:50.751 7132-7132/com.navigation.android E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.navigation.android, PID: 7132
java.lang.IllegalStateException: Fragment already added: FragmentFirst{d2a554d (20ca6825-e304-4157-8514-353a57c40268) id=0x7f080059 class com.navigation.android.tabs.firsttab.FragmentFirst}
at androidx.fragment.app.FragmentManagerImpl.addFragment(FragmentManagerImpl.java:1379)
at androidx.fragment.app.BackStackRecord.executePopOps(BackStackRecord.java:465)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2076)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.popBackStackImmediate(FragmentManagerImpl.java:310)
at androidx.fragment.app.FragmentManagerImpl.popBackStackImmediate(FragmentManagerImpl.java:253)
at androidx.fragment.app.FragmentManagerImpl.handleOnBackPressed(FragmentManagerImpl.java:233)
at androidx.fragment.app.FragmentManagerImpl$1.handleOnBackPressed(FragmentManagerImpl.java:108)
at androidx.activity.OnBackPressedDispatcher.onBackPressed(OnBackPressedDispatcher.java:189)
at androidx.activity.ComponentActivity.onBackPressed(ComponentActivity.java:286)
at android.app.Activity.onKeyUp(Activity.java:3169)
at android.view.KeyEvent.dispatch(KeyEvent.java:3383)
at android.app.Activity.dispatchKeyEvent(Activity.java:3452)
at androidx.core.app.ComponentActivity.superDispatchKeyEvent(ComponentActivity.java:122)
at androidx.core.view.KeyEventDispatcher.dispatchKeyEvent(KeyEventDispatcher.java:84)
at androidx.core.app.ComponentActivity.dispatchKeyEvent(ComponentActivity.java:140)
at androidx.appcompat.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:558)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
at androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent(AppCompatDelegateImpl.java:2814)
at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:563)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:6055)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5910)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5363)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5416)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5382)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5541)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5390)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5598)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5363)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5416)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5382)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5390)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5363)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5416)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5382)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5574)
at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:5743)
at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:3407)
at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2854)
at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2845)
at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:3384)
at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
at android.os.MessageQueue.nativePollOnce(Native Method)
2020-02-27 13:39:50.751 7132-7132/com.navigation.android E/AndroidRuntime: at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:181)
at android.app.ActivityThread.main(ActivityThread.java:7099)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
谢谢你的帮助。
解决方案
您应该在加载到视图之前检查每个片段,然后决定是否添加它们,上面的代码也可以正常工作。
if(fragmentName.isAdded(){
return;
}
推荐阅读
- python - 如果我想在遍历数组时比较数组中的元素怎么办
- javascript - 制作条形圆形 echarts
- mongodb - 如何覆盖 MongoDB 源连接器中的 Kafka 主题配置?
- javascript - 当我将变量用于选择器时,该事件不会触发
- python - Pandas read_csv():列包含数据框,但被读取为字符串
- android - 停止安卓导航栏
- php - 如何在 Laravel 中为自定义注册表单设置自定义自动登录
- javascript - 另一个窗口的Javascript关闭模式
- javascript - 在 Google Analytics 可跟踪点击后显示 mailto 链接
- r - 在 R 中创建一个带有 X 试验、Y 代表和 Z 图的 data.table