【发布时间】:2023-03-15 09:48:02
【问题描述】:
我编写了一个在两个片段之间切换的虚拟活动。当您从 FragmentA 转到 FragmentB 时,FragmentA 被添加到后堆栈。但是,当我返回 FragmentA(通过按回)时,会创建一个全新的 FragmentA,并且它所处的状态会丢失。我感觉我和this 的问题一样,但我已经包含了一个完整的代码示例来帮助根除这个问题:
public class FooActivity extends Activity {
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, new FragmentA());
transaction.commit();
}
public void nextFragment() {
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, new FragmentB());
transaction.addToBackStack(null);
transaction.commit();
}
public static class FragmentA extends Fragment {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View main = inflater.inflate(R.layout.main, container, false);
main.findViewById(R.id.next_fragment_button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
((FooActivity) getActivity()).nextFragment();
}
});
return main;
}
@Override public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save some state!
}
}
public static class FragmentB extends Fragment {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.b, container, false);
}
}
}
添加了一些日志消息:
07-05 14:28:59.722 D/OMG ( 1260): FooActivity.onCreate
07-05 14:28:59.742 D/OMG ( 1260): FragmentA.onCreateView
07-05 14:28:59.742 D/OMG ( 1260): FooActivity.onResume
<Tap Button on FragmentA>
07-05 14:29:12.842 D/OMG ( 1260): FooActivity.nextFragment
07-05 14:29:12.852 D/OMG ( 1260): FragmentB.onCreateView
<Tap 'Back'>
07-05 14:29:16.792 D/OMG ( 1260): FragmentA.onCreateView
它永远不会调用 FragmentA.onSaveInstanceState 并且当您回击时它会创建一个新的 FragmentA。但是,如果我在 FragmentA 上并锁定屏幕,则会调用 FragmentA.onSaveInstanceState。太奇怪了......我期望添加到后堆栈的片段不需要重新创建是错误的吗? docs 是这样说的:
然而,如果您在移除片段时调用 addToBackStack(), 然后片段停止并在用户导航时恢复 返回。
【问题讨论】:
-
@Jan-Henk 必须获取的东西呢?例如,
ListView的滚动位置。附加滚动侦听器和更新实例变量似乎太多了。 -
@JakeWharton 我同意这应该更容易,但据我所知,没有办法解决这个问题,因为当从后台堆栈恢复片段时会调用 onCreateView。但我可能是错的:)
-
onCreate 不会被调用。那么显然它是在重复使用同一个实例但再次调用 onCreateView ?瘸。我想我可以缓存 onCreateView 的结果,如果再次调用 onCreateView 就返回现有视图。
-
正是我一直在寻找的时间。你能发布你是如何使用实例变量实现这一点的吗?
-
所以我最近在github.com/frostymarvelous/Folio 开始了自己的实现,遇到了一个问题。在开始 OOM 崩溃之前,我能够创建大约 5 个复杂的页面/片段。这就是把我带到这里的原因。隐藏和显示是不够的。视图太占内存了。
标签: android android-fragments back-stack