FragmentTransaction 替换方法无法正常工作
FragmentTransaction replace method doesn't work properly
我在替换 FrameLayout
容器内的片段时遇到错误。
第一次启动应用程序时一切正常,但是当我隐藏应用程序然后恢复它时,当调用 FragmentTransaction.replace
方法时片段开始相互重叠
我见过几乎所有关于此类问题的 Whosebug 问题,但我无法解决此问题
代码:
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
添加初始片段:
getSupportFragmentManager().beginTransaction()
.add(R.id.frame, RequestFragment.newInstance(), REQUEST_FRAGMENT_TAG)
.commit();
替换:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
switch (menuItem.getItemId()) {
case R.id.request:
ft.replace(R.id.frame, RequestFragment.newInstance(), REQUEST_FRAGMENT_TAG);
ft.commit();
return true;
case R.id.finished:
ft.replace(R.id.frame, FinishedFragment.newInstance(), FINISHED_FRAGMENT_TAG);
ft.commit();
return true;
case R.id.questions:
ft.replace(R.id.frame, QuestionsFragment.newInstance(), QUESTIONS_FRAGMENT_TAG);
ft.commit();
return true;
default:
return true;
}
很难说,因为您的代码没有提供关于何时 运行 的上下文,但我怀疑问题出在您添加初始片段时。
您调用的是 add
而不是 replace
,后者只会将新片段添加到任何现有片段之上。即使容器还没有包含任何东西,使用 replace 也完全没问题。
片段在 FragmentManager
中存活,并在 Activity
重新启动时自动重新附加到它们的容器。正确的步骤是在添加新的之前检查现有的 Fragment
。
添加初始片段
Fragment f=getSupportFragmentManager().findFragmentById(R.id.frame);
if (f==null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, RequestFragment.newInstance(), REQUEST_FRAGMENT_TAG).commit();
}
此外,在调试时使用日志记录 getSupportFragmentManager().getFragments().size();
也很有帮助。它可以让您了解 FragmentManager 中当前有多少片段,并可以突出显示代码中的潜在问题。例如,如果每次旋转设备时计数都增加,则说明您正在添加片段而不是检查现有片段。
尝试使用 FragmentTransaction.commitAllowingStateLoss() 而不是使用 commit()
最后我没有调用 commit 方法。
这有时是因为片段背景。尝试为堆栈中的所有片段设置纯色背景,使其不为空或设置为@null。
我在替换 FrameLayout
容器内的片段时遇到错误。
第一次启动应用程序时一切正常,但是当我隐藏应用程序然后恢复它时,当调用 FragmentTransaction.replace
方法时片段开始相互重叠
我见过几乎所有关于此类问题的 Whosebug 问题,但我无法解决此问题
代码:
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
添加初始片段:
getSupportFragmentManager().beginTransaction()
.add(R.id.frame, RequestFragment.newInstance(), REQUEST_FRAGMENT_TAG)
.commit();
替换:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
switch (menuItem.getItemId()) {
case R.id.request:
ft.replace(R.id.frame, RequestFragment.newInstance(), REQUEST_FRAGMENT_TAG);
ft.commit();
return true;
case R.id.finished:
ft.replace(R.id.frame, FinishedFragment.newInstance(), FINISHED_FRAGMENT_TAG);
ft.commit();
return true;
case R.id.questions:
ft.replace(R.id.frame, QuestionsFragment.newInstance(), QUESTIONS_FRAGMENT_TAG);
ft.commit();
return true;
default:
return true;
}
很难说,因为您的代码没有提供关于何时 运行 的上下文,但我怀疑问题出在您添加初始片段时。
您调用的是 add
而不是 replace
,后者只会将新片段添加到任何现有片段之上。即使容器还没有包含任何东西,使用 replace 也完全没问题。
片段在 FragmentManager
中存活,并在 Activity
重新启动时自动重新附加到它们的容器。正确的步骤是在添加新的之前检查现有的 Fragment
。
添加初始片段
Fragment f=getSupportFragmentManager().findFragmentById(R.id.frame);
if (f==null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.frame, RequestFragment.newInstance(), REQUEST_FRAGMENT_TAG).commit();
}
此外,在调试时使用日志记录 getSupportFragmentManager().getFragments().size();
也很有帮助。它可以让您了解 FragmentManager 中当前有多少片段,并可以突出显示代码中的潜在问题。例如,如果每次旋转设备时计数都增加,则说明您正在添加片段而不是检查现有片段。
尝试使用 FragmentTransaction.commitAllowingStateLoss() 而不是使用 commit()
最后我没有调用 commit 方法。
这有时是因为片段背景。尝试为堆栈中的所有片段设置纯色背景,使其不为空或设置为@null。