在使用Android文档中的片段的example中,当应用程序处于“双视图”模式时,只要应用程序需要显示不同标题的详细信息,就会重新创建详细信息片段。 FragmentTransaction.replace()
用于将每个旧的详细信息片段实例换成新的。
这是推荐的做法吗?当真正的意图(没有双关语意图)要更新UI显示的内容而不是UI本身时,创建新的UI实例并不浪费。在我看来,创建新实例的唯一原因是,如果有人打算将它们添加到backstack,那么用户可以回溯步骤。否则,直接更新片段是否安全/可取?
在该示例的情况下,它将意味着沿DetailsFragment.setShownIndex()
行的方法。这将被调用,传入新的标题索引,而不是重新创建DetailsFragment
。
假设我们有一个示例版本,其中一个活动管理两个片段,但一次只显示一个片段,根据需要交换每个片段。活动是否可以创建每个片段的实例,保留对每个片段的引用,然后根据需要简单地添加或删除这两个实例?
这可能是一个棘手的后果,当标题片段处于resumed
状态时(即在'前景'中),选择标题将导致调用DetailsFragment.setShownIndex()
细节片段处于stopped
状态的时间。
好主意?不好主意?
提前致谢。
答案 0 :(得分:5)
就像你说的,创建新Fragment实例的主要原因是为了便于使用后端堆栈。重用现有的片段(使用FragmentManager.findFragmentById()
或FragmentManager.findFragmentByTag()
查找)也非常安全。有时您需要充分利用isVisible()
,isRemoving()
等片段方法,以便在DetailsFragment
为stopped
时不会非法引用UI组件。
无论如何,在您建议的包含2个片段的单一窗格活动中,您的setShownIndex
方法可以在DetailsFragment
中设置一个加载在onCreateView
或onActivityCreated
中的私有字段。< / p>
如,
DetailsFragment df = getFragmentManager().findFragmentByTag("details");
if (df != null) {
df.setShownIndex(getSelectedIndex());
} else {
df = DetailsFragment.newInstance(getSelectedIndex());
}
fragmentTransaction.replace(R.id.frame, df, "details").commit();
在这两种情况下,无论是新创建还是重复使用df,onCreateView
和onActivityCreated
都会在DetailsFragment
添加到容器时调用。
但是如果你想要一个后台堆栈,我强烈建议你只创建新实例,否则你只是为DetailsFragment
的内容实现自己的后台堆栈。
答案 1 :(得分:1)
我尝试了以下代码,它适用于我:
private void replaceFragment(Class fragmentClass, String FRAGMENT_NAME, android.support.v4.app.FragmentManager fragmentManager) {
Fragment fragment = null;
String backStateName = fragmentClass.getName(); // nome della classe del Fragment
Log.d("Fragment: ", "Creazione Fragment: "+backStateName);
Boolean fragmentExit = isFragmentInBackstack(fragmentManager, backStateName);
if (fragmentExit) { //Il Fragment è presente nello stacback
// Fragment exists, go back to that fragment
//// you can also use POP_BACK_STACK_INCLUSIVE flag, depending on flow
fragmentManager.popBackStackImmediate(fragmentClass.getName(), 0);
} else {
// se non esiste lo aggiungiamo
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Inizializzo la transazione del Fragment
android.support.v4.app.FragmentTransaction ft = fragmentManager.beginTransaction();
ft.setCustomAnimations(
R.anim.fragment_slide_left_enter,
R.anim.fragment_slide_left_exit,
R.anim.fragment_slide_right_enter,
R.anim.fragment_slide_right_exit);
ft.replace(R.id.frameLayout_contentMain, fragment, FRAGMENT_NAME);
ft.addToBackStack(fragmentClass.getName());
ft.commit();
// Recupero il numero di Fragment presenti
Integer nFragment = fragmentManager.getBackStackEntryCount();
Log.d("Fragment: ", "Numero di Fragment: "+nFragment);
}
}
要确定片段是否已经在StackBack中,请执行此函数:
public static boolean isFragmentInBackstack(final android.support.v4.app.FragmentManager fragmentManager, final String fragmentTagName) {
for (int entry = 0; entry < fragmentManager.getBackStackEntryCount(); entry++) {
if (fragmentTagName.equals(fragmentManager.getBackStackEntryAt(entry).getName())) {
return true;
}
}
return false;
}
我希望我能帮到你