确定更新片段而不是创build新的实例?

在Android文档中使用片段的示例中,当应用程序处于“双视图”模式时,只要应用程序需要显示不同标题的详细信息,就会重新创build细节片段。 FragmentTransaction.replace()用于将每个旧的细节片段实例换出一个新的细节。

这是推荐的做法吗? 当真正的意图(不是双关语意图)是更新UI显示的内容而不是UI本身时,创build新的UI实例是不是浪费。 在我看来,创build新实例的唯一原因是如果有人想将它们添加到后台,用户可以回溯步骤。 否则,是否安全/build议直接更新片段?

在这个例子中,这意味着沿着DetailsFragment.setShownIndex() 。 这将被称为传递新的标题索引,而不是重新创buildDetailsFragment

假设我们有一个示例的版本,其中一个活动同时pipe理两个片段,但是每次只显示一个片段,根据需要将每个片段交换出来。 活动是否可以创build每个片段的实例,保留每个片段的引用,然后根据需要简单地添加或删除这两个实例?

一个可能的粘滞的结果是,当标题片段处于resumed状态(即在“前景”)时,select标题将导致在详细片段处于中时调用DetailsFragment.setShownIndex() stopped状态。

好主意? 馊主意?

提前致谢。

Solutions Collecting From Web of "确定更新片段而不是创build新的实例?"

就像你说的那样,创build新Fragment实例的主要原因是为了方便使用后端堆栈。 重复使用现有的Fragment(使用FragmentManager.findFragmentById()FragmentManager.findFragmentByTag() )查找也是非常安全的。 有时你需要充分利用像isVisible()isRemoving()等片段方法,以便在DetailsFragment stopped时不会非法引用UI组件。

无论如何,在您提出的带有2个片段的单窗格活动中,您的setShownIndex方法可以在DetailsFragment设置专用字段,该字段在onCreateViewonActivityCreated加载。

例如,

 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是新创build的还是重用的,当DetailsFragment被添加到容器时, onCreateViewonActivityCreated都会被调用。

但是如果你想要一个后退堆栈,我强烈build议只是创build新的实例,否则你只是为了DetailsFragment的内容实现你自己的后退堆栈。

我已经尝试了下面的代码,它适用于我:

 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); } } 

要确定Fragment是否已经在StackBack中执行此function:

 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; } 

我希望我能帮助你