【发布时间】:2016-08-10 15:07:17
【问题描述】:
我有一个 Android 活动,它保存和管理六个片段,片段是流程中的一个步骤,一些片段被替换,其中一些被添加。
Activity 只是使用 Framelayout 作为片段的容器,如下所示:
<FrameLayout
android:id="@+id/content"
android:layout_below="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent" />
那么片段的流程是这样的:
//Activity starts, add first Fragment
fragmentManager.beginTransaction().replace(R.id.content, FirstFragment.newInstance(listOfItems)).commit();
然后
//User pressed button, activity got callback from first fragment
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content, fragment2);
transaction.addToBackStack("frag2");
transaction.commit();
然后
//Another callback from Frag2, perform the add of frag 3
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.content, fragment3);
transaction.addToBackStack("frag3");
transaction.commit();
等等……
我还像这样从 Activity 管理后台堆栈:
//Controlling the back stack when the user selects the soft back button in the toolbar
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
if (fragmentManager.getBackStackEntryCount() == 0) {
super.onBackPressed();
overridePendingTransition(R.anim.no_change, R.anim.slide_down);
} else {
if(!BaseFragment.handleBackPressed(getSupportFragmentManager())){
super.onBackPressed();
Fragment fragment = fragmentManager.getFragments()
.get(fragmentManager.getBackStackEntryCount());
fragment.onResume(); //Make sure the fragment that is currently at the top of the stack calls its onResume method
}
}
return true;
}
return super.onOptionsItemSelected(item);
}
//Controlling the back stack when the user selects the "hardware" back button
@Override
public void onBackPressed() {
if (fragmentManager.getBackStackEntryCount() == 0) {
super.onBackPressed();
overridePendingTransition(R.anim.no_change, R.anim.slide_down);
} else {
if(!BaseFragment.handleBackPressed(getSupportFragmentManager())){
super.onBackPressed();
Fragment fragment = fragmentManager.getFragments()
.get(fragmentManager.getBackStackEntryCount());
fragment.onResume(); //Make sure the fragment that is currently at the top of the stack calls its onResume method
}
}
}
我的问题是我打开应用程序并转到加载片段的此活动,然后通过流程到某个阶段(我还没有缩小范围)然后我按下主页按钮并空白我的屏幕.现在经过一段时间后,当我再次打开应用程序时,它会在我留下的片段上打开,但一切似乎都搞砸了,当我按下返回时,它似乎弹出了错误的片段,并且 UI 与不同的片段混合在一起。
我的猜测是,当我再次打开应用程序时,Activity onResume 或 Fragment onResume 或某些生命周期事件被调用,但我没有正确处理?
所以我想知道在像我这样使用 Fragment 模式时是否应该遵守最佳实践、指南或模式?
【问题讨论】:
-
我认为这不是问题的原因,但是没有必要在从后台重新添加的 Fragment 上调用“onResume”。如果片段从“替换”中删除,则重新添加时将再次调用“onResume”。如果片段从未被移除,那么状态将保持不变。
-
是的,我同意,但你是对的,这不是问题的原因,我在片段的 onResume 中所做的只是调用 Activity 来设置工具栏的标题。
-
好吧,你必须在 Fragment 本身上调用“super.onResume()”,因为它需要做自己的事情,乱序调用可能会导致意外行为。
-
你为什么在 fragment3 中使用
transaction.add? (无论如何我认为one Activity and many Fragments模式很难维护。) -
因为我想在片段 2 的顶部添加片段 3 并将片段 2 保留在那里,因为片段 3 是用户选择,然后他们移回片段 2
标签: android android-fragments android-lifecycle fragment-backstack