我怎样才能保持碎片状态时添加到后退堆栈?堆栈、碎片、状态

2023-09-11 20:15:25 作者:我要三宫六院七十二男妃

我已经写了两个片段之间切换的虚活动。当您从碎裂去FragmentB,碎裂被添加到后退堆栈。然而,当我回到碎裂(由pressing回),一个全新的碎裂创建和所处的状态丢失。给我的感觉我同样的事情this的问题,但我已经包含了完整的code样品,以帮助深挖问题:

 公共类FooActivity延伸活动{
  @覆盖公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    最后FragmentTransaction交易= getFragmentManager()的BeginTransaction()。
    transaction.replace(android.R.id.content,新碎裂());
    器transaction.commit();
  }

  公共无效nextFragment(){
    最后FragmentTransaction交易= getFragmentManager()的BeginTransaction()。
    transaction.replace(android.R.id.content,新FragmentB());
    transaction.addToBackStack(空);
    器transaction.commit();
  }

  公共静态类碎裂扩展片段{
    @覆盖公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
        捆绑savedInstanceState){
      最后查看主= inflater.inflate(R.layout.main,集装箱,假);
      main.findViewById(R.id.next_fragment_button).setOnClickListener(新View.OnClickListener(){
        公共无效的onClick(视图v){
          ((FooActivity)getActivity())nextFragment()。
        }
      });
      返回主;
    }

    @覆盖公共无效的onSaveInstanceState(包outState){
      super.onSaveInstanceState(outState);
      //保存一些状态!
    }
  }

  公共静态类FragmentB扩展片段{
    @覆盖公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
        捆绑savedInstanceState){
      返回inflater.inflate(R.layout.b,集装箱,假);
    }
  }
}
 

通过一些日志消息说:

  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
<在碎裂&GT点击按钮;
07-05 14:29:12.842 D / OMG(1260):FooActivity.nextFragment
07-05 14:29:12.852 D / OMG(1260):FragmentB.onCreateView
<点击返回>
07-05 14:29:16.792 D / OMG(1260):FragmentA.onCreateView
 

这是从来没有打电话FragmentA.onSaveInstanceState,当你打回它创建了一个新的碎裂。但是,如果我在碎裂,我锁定屏幕,FragmentA.onSaveInstanceState不会被调用。太奇怪了......我错在期待加入到背堆栈并不需要再创造一个片段?下面就是文档说:

  

然而,如果你调用addToBackStack()删除片段时,   然后该片段被停止,如果用户导航将会恢复   回来了。

解决方案 新增表情动画 个人状态,文章浮窗大改动 微信 8.0 更新了啥

如果你从后面堆栈不回的片段重新创建的片段,但重新使用相同的实例,并开始与 onCreateView()在片段生命周期,请参阅片段生命周期。

所以,如果你想存储的状态,你应该使用实例变量和不可以依赖的onSaveInstanceState()

I've written up a dummy activity that switches between two fragments. When you go from FragmentA to FragmentB, FragmentA gets added to the back stack. However, when I return to FragmentA (by pressing back), a totally new FragmentA is created and the state it was in is lost. I get the feeling I'm after the same thing as this question, but I've included a complete code sample to help root out the issue:

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

With some log messages added:

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

It's never calling FragmentA.onSaveInstanceState and it creates a new FragmentA when you hit back. However, if I'm on FragmentA and I lock the screen, FragmentA.onSaveInstanceState does get called. So weird...am I wrong in expecting a fragment added to the back stack to not need re-creation? Here's what the docs say:

Whereas, if you do call addToBackStack() when removing a fragment, then the fragment is stopped and will be resumed if the user navigates back.

解决方案

If you return to a fragment from the back stack it does not re-create the fragment but re-uses the same instance and starts with onCreateView() in the fragment lifecycle, see Fragment lifecycle.

So if you want to store state you should use instance variables and not rely on onSaveInstanceState().