我编写了一个在两个片段之间切换的虚拟活动。当您从 FragmentA 转到 FragmentB 时,FragmentA 被添加到后堆栈。但是,当我返回 FragmentA(通过按回)时,会创建一个全新的 FragmentA,并且它所处的状态会丢失。我已经包含了一个完整的代码示例来帮助根除这个问题:
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。太奇怪了......我期望添加到后台堆栈的片段不需要重新创建是错误的吗?这是文档所说的:
然而,如果您在删除片段时确实调用了 addToBackStack(),那么片段将停止,并且如果用户导航回来,它将恢复。
如果您从后台堆栈返回片段,它不会重新创建片段,而是重新使用相同的实例并从onCreateView()片段生命周期开始,请参阅片段生命周期。
onCreateView()
所以如果你想存储状态,你应该使用实例变量而 不是 依赖onSaveInstanceState().
onSaveInstanceState()