如何保存具有listview的Fragment状态

时间:2013-07-23 12:53:56

标签: java android android-listview fragment

这是一种情况。我想从Fragment A->导航; B->下进行。

在B片段中有listview。单击项目时,打开详细视图C Fragment。 当然我使用了替换方法并添加了addtoBackStack(null),而事务从B到C,所以在Back上按下它返回到B.

一切顺利。但是当我从C返回B时,视图正在刷新,因此再次调用web服务。我不想这样做。我想用listview保留B Fragment状态。

我收到了一些保留实例的帖子,但它并没有那么多帮助。

非常感谢任何帮助。

感谢。

4 个答案:

答案 0 :(得分:12)

如解释here,您可以使用onSaveInstanceState()将数据保存在Bundle中,并在onRestoreInstanceState()方法中检索该数据。

通常提到setRetainState(true)作为将ui状态保留在片段中的方法,但它不适合你,因为你正在使用backstack。

所以一个好方法可能是在onSaveInstanceState()中保存scrollposition并将其恢复为onRestoreInstanceState(),如下所示:

public class MyListFragment extends ListFragment {

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

     int index = this.getListView().getFirstVisiblePosition();
     View v = this.getListView().getChildAt(0);
     int top = (v == null) ? 0 : v.getTop();

     outState.putInt("index", index);
     outState.putInt("top", top);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    [...]
    if (savedInstanceState != null) {
        // Restore last state for checked position.
        index = savedInstanceState.getInt("index", -1);
        top = savedInstanceState.getInt("top", 0);
    }
    if(index!=-1){
     this.getListView().setSelectionFromTop(index, top);
  }

}

您还可以找到更详细的类似示例here

答案 1 :(得分:2)

我通过在onCreate()而不是onCreateView()上创建我的适配器来解决这个问题。

这是因为(我认为)添加到backstack的片段丢失了View,然后它必须重新创建视图。 onCreateView()被调用并顺便重新创建你的适配器。

答案 2 :(得分:0)

你可以在oncreate中保存定义你的ui。 在onCreateView中,只添加布局。 所以视图状态可以保存完美。

这是我的sv:

在oncreate中

 LayoutInflater inflater = (LayoutInflater)
            ctx.getSystemService(ctx.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.pulltorefreshgridview, null);
    mPullRefreshGridView = (PullToRefreshGridView) view
            .findViewById(R.id.listcate_pullrefresh_gridview);

强文 在onCreateView

if (rootView != null) ((LinearLayout)rootView).removeAllViews();
View v = inflater.inflate(R.layout.listcate_fragment, container, false);
rootView = v;


    ((LinearLayout) v).addView(mPullRefreshGridView,
            new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.FILL_PARENT,
                    LinearLayout.LayoutParams.FILL_PARENT));

答案 3 :(得分:0)

我认为您可以在离开片段B之前保存ListView的位置。 也许在片段B的 onStop()中这样做。当你回去时,你可以获取该位置并将其恢复到ListView,例如在片段B的 onStart()中执行此操作。 位置数据可能保存在Activity中,因此即使片段已分离也不会丢失。

有一点需要注意(我已经被这个困住了),如果保存的位置数据由后台服务更新,你应该避免在生命周期阶段 onStart()之前将它恢复到ListView片段B的,因为实际上,框架将在离开片段之前保存视图的状态,并在返回时恢复它。因此,如果您在框架之前恢复您的位置,框架的恢复数据将覆盖您的位置。