在我的应用程序中,我必须处理需要大量片段进行实例化的不同情况。
为了更好地维护用户体验,我管理了Fragment的BackStack,有时还管理了一个子片段的backstack。
一切正常,直到用户填写了这个背包的一部分。
现在,如果用户想要进入先前添加到backstack的片段,系统会处理请求Pop Fragments,直到用户请求为止。
这样就不会调用片段的newInstance()方法,因为(我相信)片段是从内存中恢复的。
问题在于:
有时,在我的应用程序中,在不同的地方,我创建了相同片段的实例,但在Fragment.newInstance()中传递了不同的参数;
通过这种方式,我可以以不同的方式使用相同的片段。
但是,如果已经实例化了相同的片段,系统将从BackStack中恢复旧的片段实例。
真实情况:
片段A - >我的片段;
实例A1 ---->我从newInstance获得的实例(参数1);
实例A2 ---->我从newInstance获得的实例(参数2);
在应用程序中有一个DrawerMenu有2个声音,第一个呼叫并显示A1,第二个呼叫并显示A2。
用户打开应用程序,然后单击第一个语音,然后以正确的方式显示A1。
比用户点击第二个声音,A.newInstance(参数2);被调用,但系统从backstack恢复A1,而A1显示而不是A2。
感谢。
修改
我的FragmentManager的事务代码,此方法保留在MainActivity中。
当我想要更改片段时,我调用changeFragment(FragmentA.newIstance(Parameter1),true,true);
布尔参数用于Backstack和动画
public void changeFragment(Fragment frag, boolean saveInBackstack, boolean animate) {
String backStateName = ((Object) frag).getClass().getName();
String TAG ="Fragment manager";
try {
FragmentManager manager = getSupportFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped && manager.findFragmentByTag(backStateName) == null) {
//fragment not in back stack, create it.
FragmentTransaction transaction = manager.beginTransaction();
if (animate) {
Log.d(TAG, "Change Fragment: animate");
transaction.setCustomAnimations(R.anim.fadein,R.anim.fadeout, R.anim.fadein,R.anim.fadeout);
}
transaction.replace(R.id.framelayout_container, frag, backStateName);
if (saveInBackstack) {
Log.d(TAG, "Change Fragment: addToBackTack " + backStateName);
transaction.addToBackStack(backStateName);
} else {
Log.d(TAG, "Change Fragment: NO addToBackTack");
}
transaction.commit();
} else {
// AnimationShake(findViewById(R.id.fragment_holder));
}
} catch (IllegalStateException exception) {
Log.w(TAG, "Unable to commit fragment, could be activity as been killed in background. " + exception.toString());
}
}
这是ChildFragmentManager的方法,我在片段中使用它,它应该处理其中的其他子片段,我以与之前相同的方式调用它:
public void changeFragmentChild(Fragment frag, boolean saveInBackstack, boolean animate) {
String backStateName = ((Object) frag).getClass().getName();
String TAG ="Fragment manager";
try {
FragmentManager manager = getChildFragmentManager();
boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped && manager.findFragmentByTag(backStateName) == null) {
//fragment not in back stack, create it.
FragmentTransaction transaction = manager.beginTransaction();
if (animate) {
Log.d(TAG, "Change Fragment: animate");
transaction.setCustomAnimations(R.anim.enter_from_right,R.anim.exit_from_left, R.anim.enter_from_left,R.anim.exit_from_right);
}
transaction.replace(R.id.chilcontainer, frag, backStateName);
if (saveInBackstack) {
Log.d(TAG, "Change Fragment: addToBackTack " + backStateName);
transaction.addToBackStack(backStateName);
} else {
Log.d(TAG, "Change Fragment: NO addToBackTack");
}
transaction.commit();
} else {
// AnimationShake(findViewById(R.id.fragment_holder));
}
} catch (IllegalStateException exception) {
Log.w(TAG, "Unable to commit fragment, could be activity as been killed in background. " + exception.toString());
}
}