09-19 12:23:01.084: E/AndroidRuntime(24169): FATAL EXCEPTION: main
09-19 12:23:01.084: E/AndroidRuntime(24169): Process: com.example.loan, PID: 24169
09-19 12:23:01.084: E/AndroidRuntime(24169): java.lang.IllegalStateException: Fragment already added: FormFragment{428f10c8 #1 id=0x7f050055 form}
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1192)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:722)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1533)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.support.v4.app.FragmentManagerImpl$2.run(FragmentManager.java:489)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:450)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.os.Handler.handleCallback(Handler.java:733)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.os.Handler.dispatchMessage(Handler.java:95)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.os.Looper.loop(Looper.java:136)
09-19 12:23:01.084: E/AndroidRuntime(24169): at android.app.ActivityThread.main(ActivityThread.java:5068)
09-19 12:23:01.084: E/AndroidRuntime(24169): at java.lang.reflect.Method.invokeNative(Native Method)
09-19 12:23:01.084: E/AndroidRuntime(24169): at java.lang.reflect.Method.invoke(Method.java:515)
09-19 12:23:01.084: E/AndroidRuntime(24169): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
09-19 12:23:01.084: E/AndroidRuntime(24169): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
09-19 12:23:01.084: E/AndroidRuntime(24169): at dalvik.system.NativeStart.main(Native Method)
所以,我有一个用tabhost构建的android应用程序。共有三个选项卡,在tab2中,有一个按钮用于在tab2中进行片段事务(在片段活动中调用该函数)
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.realtabcontent, mFrag);
t.addToBackStack(null);
t.commit();
如果我像这样跑,有例外:
如何解决这个问题?谢谢你的帮助
答案 0 :(得分:108)
当我们尝试在解雇之前添加相同的片段或DialogFragment两次时会发生这种情况,
只需致电
if(mFragment.isAdded())
{
return; //or return false/true, based on where you are calling from
}
话虽如此,我没有看到任何理由为什么要删除旧片段并再次添加相同的片段,因为我们可以通过简单地将参数传递给片段内的方法来更新UI /数据
答案 1 :(得分:7)
您只需检查下面提到的片段中的一个条件:
if(!isAdded())
{
return;
}
isAdded =如果片段当前已添加到其活动中,则返回true。取自官方文档。 如果已经添加了该片段,则不会添加该片段
请查看以下链接以获取参考:
http://developer.android.com/reference/android/app/Fragment.html#isAdded()
答案 2 :(得分:7)
删除旧片段,以防它仍然添加,然后添加新片段:
FragmentManager fm = getSupportFragmentManager();
Fragment oldFragment = fm.findFragmentByTag("fragment_tag");
if (oldFragment != null) {
fm.beginTransaction().remove(oldFragment).commit();
}
MyFragment newFragment = new MyFragment();
fm.beginTransaction().add(newFragment , "fragment_tag");
答案 3 :(得分:5)
您必须在开始片段交易之前检查一个条件
if (!fragmentOne.isAdded()){
transaction = manager.beginTransaction();
transaction.add(R.id.group,fragmentOne,"Fragment_One");
transaction.commit();
}
这对我有用......
答案 4 :(得分:1)
有时会因为没有从相应的布局中找到正确的ID而发生。我遇到了这个问题。然后几个小时后我发现我设置了错误的recyclerview id。我改变它,对我来说很好。
因此,请仔细检查您的片段布局。
答案 5 :(得分:1)
不将我的主体XML封装在FrameLayout的ViewGroup中时出现此错误。
错误:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".screens.home.HomeEpoxyFragment">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:overScrollMode="never"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
已解决:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".screens.home.HomeEpoxyFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:overScrollMode="never"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
希望这可能对某人有所帮助。
答案 6 :(得分:0)
对我来说,它的工作原理是:
Fragment oldFragment = manager.findFragmentByTag(READER_VIEW_POPUP);
if (oldFragment != null) {
manager.beginTransaction().remove(oldFragment).commit();
}
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
答案 7 :(得分:0)
如果您在FragmentStatePagerAdapter
的{{1}}中创建了一个已经存在的商品,甚至可能会发生:
ViewPager
({override fun getItem(position: Int): Fragment {
return tabs[0] // Right variant: tabs[position]
}
是选项卡中的片段列表)。
答案 8 :(得分:0)
令我惊讶的是,我两次调用了片段事务,犯了一个愚蠢的错误:
if (!FirebaseManager.isClientA && !FirebaseManager.isClientB) {
fragment = new FragmentA();
getFragmentManager().beginTransaction().add(R.id.fragment_frame, fragment, null).addToBackStack("").commit();
} else if (FirebaseManager.isClientB) {
fragment = new FragmentB();
} else {
fragment = new FragmentC();
}
getFragmentManager().beginTransaction().add(R.id.fragment_frame, fragment, null).addToBackStack("").commit();
确保您没有犯同样的错误。
答案 9 :(得分:0)
添加如下片段
FragmentTransaction t = getSupportFragmentManager().beginTransaction();
t.replace(R.id.realtabcontent, mFrag);
t.addToBackStack(null);
t.commitNowAllowingStateLoss();
答案 10 :(得分:0)
您可以尝试以下方法:
if (dialogFolderGallery.isAdded()) {
dialogFolderGallery.dismiss();
} else { //bla...bla..
}
答案 11 :(得分:0)
我在 Fragment 中错误地使用了我的 ViewModel 时遇到了这个错误:
//This is wrong!
MyViewModel viewModel = new MyViewModel(getActivity().getApplication());
正确方法:
viewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(MyViewModel.class);
答案 12 :(得分:0)
这里是我的 Dialog Fragment 解决方案(您也可以将这个概念用于片段类)
我尝试通过多次快速点击按钮来单击显示对话框片段。
FragmentManager fm = getSupportFragmentManager();
Fragment oldFragment = fm.findFragmentByTag("wait_modal");
if(oldFragment != null && oldFragment.isAdded())
return;
if(oldFragment == null && !please_wait_modal.isAdded() && !please_wait_modal.isVisible()){
fm.executePendingTransactions();
please_wait_modal.show(fm,"wait_modal");
}