我在Activity中有几个片段。在做了一些过程后,我使用下面的代码关闭片段。
if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 0) {
getActivity().getSupportFragmentManager().popBackStackImmediate();
}
但是在线popBackStackImmediate()抛出错误
Process: com.TestProject.testpro, PID: 17966
java.lang.IllegalStateException: Fragment no longer exists for key f0: index 1
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:879)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:215)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1481)
at android.view.View.dispatchRestoreInstanceState(View.java:14746)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3121)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127)
at android.view.View.restoreHierarchyState(View.java:14724)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:475)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1329)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executePopOps(BackStackRecord.java:807)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2360)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:823)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:776)
at com.TestProject.testpro.application.fragments.WFMUpgradeToAffinityFragmentAN$WFMStoreProfileIdReceiver.onReceive(WFMUpgradeToAffinityFragmentAN.java:1064)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
没有其他崩溃关闭片段。我找不到这个问题的确切解决方案。请帮帮我。
编辑:
我使用以下函数来调用片段。
void showContentFragment(Fragment newFragment, String backStackName) {
//Log.e(TAG, "showContentFragment- " + "BackstackName: "+ backStackName);
FragmentManager mFragmentManager = getActivity().getSupportFragmentManager();
if (newFragment != null) {
//updateNavigation(backStackName);
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.replace(R.id.fragment_container, newFragment);
if (backStackName != null && !backStackName.isEmpty()) {
ft.addToBackStack(backStackName);
}
ft.commit();
}
}
答案 0 :(得分:3)
对于ViewPager2,只需使用viewPager.setSaveEnabled(false);
答案 1 :(得分:0)
请按照以下步骤添加活动中的片段
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, yourFragment, yourFragment.class.getSimpleName()).addToBackStack(yourFragment.class.getSimpleName())
.commit();
使用此代码从您的片段中调用popBackStack()
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
}
确保您正在导入正确的片段类
import android.support.v4.app.Fragment;
答案 2 :(得分:0)
在Fragment类中添加下面的代码,根据doc,它返回用于在Fragment准备关闭时将Views移出场景的Transition。
@Override
public Object getReturnTransition() {
return super.getReturnTransition();
}
答案 3 :(得分:0)
您的堆栈跟踪显示您正在使用ViewPager
并自行操纵Backstack。
这可能不是一个好主意 - 让你的ViewPager
管理后台(它做得好)或自己完全管理它。
请注意,在自己管理backstack时,您必须考虑恢复实例状态(堆栈跟踪中的哪些功能)和Fragment lifecycle。
这意味着在内存不足的情况下,您的Activity和Fragments将被停止。如果您没有正确保存实例状态,那么当它们重新启动时,您将收到类似上面的错误。如果片段的工作流程很简单,则可以使用ViewPager
来避免所有这些。
答案 4 :(得分:0)
public void showContentFragment(Fragment fragment, Bundle bundle, boolean addToBackStack) {
if (bundle != null)
fragment.setArguments(bundle);
tag = fragment.getClass().getSimpleName();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right);
ft.replace(R.id.container_internal, fragment, tag);
fragment.setRetainInstance(true); // IMPORTANT
if (addToBackStack)
ft.addToBackStack(tag);
try {
ft.commit();
} catch (Exception ex) {
ex.printStackTrace();
ft.commitAllowingStateLoss();
}
答案 5 :(得分:0)
首先,您不需要致电getActivity().getSupportFragmentManager()
。 getFragmentManager()
就足以致电FragmentManager
。
如果你在支持片段,getFragmentManager()将为您提供supportFragmentManager()
,或者它会为您提供 app.Fragment Manager 。
如果您在ViewPager中调用PopBackstack,它将无法正常工作。如果您在另一个片段中使用viewPager
。你应该只在父片段中调用popBackstack
。不在viewPager
。
尝试以下代码,它将根据后栈名称清除堆栈。
getFragmentManager.popBackStackImmediate(YourBackStackName, FragmentManager.POP_BACK_STACK_INCLUSIVE)
希望有所帮助:)
答案 6 :(得分:0)
在ViewPager适配器中,覆盖@Service
public class SubjectDAO {
@Autowired
SubjectRepository subjectRepository;
//to save a subject
public Subject save(Subject subject){
return subjectRepository.save(subject);
}
//to search all subjects
public List<Subject> findAll(){
return subjectRepository.findAll();
}
//get a subject by id
public Subject findById(Long id){
return subjectRepository.findById(id).orElse(null);
}
//delete a subject
public void delete(Long id){
subjectRepository.deleteById(id);
}
}
restoreState(state, loader)
答案 7 :(得分:0)
在我的viewPager中重写restoreState方法对我有用。
override fun restoreState(state: Parcelable?, loader: ClassLoader?) {
try {
super.restoreState(state, loader)
} catch (e: Exception) {
e.printStackTrace()
}
}
这是我的视图分页器的最终代码
class MenuTabAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
private val mFragmentList = ArrayList<Fragment>()
private val mFragmentTitleList = ArrayList<String>()
private var mCurrentPosition = -1
override fun getItem(position: Int): Fragment {
return mFragmentList[position]
}
override fun getCount(): Int {
return mFragmentList.size
}
fun addFragment(fragment: Fragment, title: String) {
mFragmentList.add(fragment)
mFragmentTitleList.add(title)
}
override fun getPageTitle(position: Int): CharSequence? {
return mFragmentTitleList[position]
}
override fun setPrimaryItem(container: ViewGroup, position: Int, `object`: Any) {
super.setPrimaryItem(container, position, `object`)
if (position !== mCurrentPosition && container is HeightWrappingViewPager) {
val fragment = `object` as Fragment
if (fragment?.view != null) {
mCurrentPosition = position
container.requestLayout()
}
}
}
override fun restoreState(state: Parcelable?, loader: ClassLoader?) {
try {
super.restoreState(state, loader)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
答案 8 :(得分:0)
在报告错误的Fragment的Adapter中重写以下方法并返回null。
@Override
public Parcelable saveState() {
return null;
}
更多详情here。