【问题标题】:savedInstanceState when restoring fragment from back stack从后台堆栈恢复片段时的 savedInstanceState
【发布时间】:2012-06-22 02:56:58
【问题描述】:

我可以在删除片段时使用savedInstanceState() 保存状态,然后在将片段从返回堆栈中弹出时恢复状态吗?当我从后台堆栈恢复片段时,savedInstanceState 包始终为空。

现在,应用流程是:创建片段 -> 删除片段(添加到后台堆栈)-> 从后台堆栈恢复片段(savedInstanceState 包为空)。

以下是相关代码:

public void onActivityCreated(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle bundle = getArguments();
    Long playlistId = bundle.getLong(Constants.PLAYLIST_ID);
    int playlistItemId = bundle.getInt(Constants.PLAYLISTITEM_ID);

    if (savedInstanceState == null) {
       selectedVideoNumber = playlistItemId;
    } else {
       selectedVideoNumber = savedInstanceState.getInt("SELECTED_VIDEO");
    }
}

public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(Constants.SELECTED_VIDEO, selectedVideoNumber);
    }

我认为问题在于onSavedInstanceState() 在被删除并被添加到后堆栈时从未被调用。如果我不能使用 onsavedInstanceState(),还有其他方法可以解决这个问题吗?

【问题讨论】:

    标签: android android-fragments bundle back-stack


    【解决方案1】:

    onSaveInstanceState (不幸的是)在片段的正常回栈重新创建中没有被调用。查看http://developer.android.com/guide/components/fragments.html#CreatingHow can I maintain fragment state when added to the back stack? 上的答案

    【讨论】:

      【解决方案2】:

      我喜欢将我在 onCreateView 返回的视图存储为一个全局变量,然后当我返回时,我只需检查一下:

      if(mBaseView != null) {
              // Remove the view from the parent
              ((ViewGroup)mBaseView.getParent()).removeView(mBaseView);
              // Return it
              return mBaseView;
          }
      

      【讨论】:

      • 不确定这是个好主意。如果保存对它的引用,这是否会破坏视图以释放内存的目的?
      • 我实际上不确定,因为我没有运行任何直接测试。然而,我的想法是这样的。当您初始化布局中的所有元素时,将这些元素中的大多数设置为全局变量是标准的,因此如果在上面的示例中由于引用而无法回收基本视图,Android 将无法回收这些视图中的任何一个,从而导致相同的内存问题。
      • 如果您需要为不同的方向膨胀不同的视图,这将不起作用。
      • 这个解决方案救了我的命。
      【解决方案3】:

      问题是片段需要有一个IdTag 与之关联,以便FragmentManager 跟踪它。

      至少有 3 种方法可以做到这一点:

      1. 在 xml 布局中为您的片段声明 Id

        android:id=@+id/<Id>
        
      2. 如果您的片段容器View 有一个Id,请使用FragmentTransaction

        FragmentTransaction  add (int containerViewId, Fragment fragment)
        
      3. 如果您的片段没有与任何View 关联(例如无头片段),请给它一个Tag

        FragmentTransaction  add (Fragment fragment, String tag)
        

      Also, see this SO answer.

      【讨论】:

        【解决方案4】:

        FWIW,我也遇到了这个问题,但在我的情况下,onSaveInstanceState 被正确调用,当智能手机上出现新的活动片段时,我推送了我的状态数据。和你一样,onActivityCreated 被称为 w/ savedInstanceState 始终为空。恕我直言,我认为这是一个错误。

        我通过创建静态 MyApplication 状态并将数据放在那里以等效于“全局变量”来解决它...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-24
          • 2022-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多