如何保存具有列表视图的Fragment的状态



下面是一个情况。我想从片段A->B->C.进行导航。

在B片段中有列表视图。点击项目,打开详细视图C Fragment。当然,我使用了替换方法,并在从B到C的交易中添加了addtoBackStack(null),这样在按下Back键时它就返回到了B。

一切顺利。但是当我从C返回到B时,视图被刷新,因此Web服务被再次调用。我不想这么做。我想用listview保留B片段状态。

我得到了一些关于保留实例的帖子,但它并没有起到多大作用。

非常感谢您的帮助。

谢谢。

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

通常提到setRetainState(true)是将ui状态保持在片段中的一种方式,但它对您不起作用,因为您使用的是backback。

因此,一个很好的方法是将滚动位置保存在onSaveInstanceState()中,并在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);
  }
}

此外,您可以在这里找到更详细的类似示例。

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

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

您可以在oncreate中保存定义您的ui。在onCreateView中时,只将其添加到布局中。因此视图状态可以保存完美。

这是我的sv:

在创建时

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

strong文本在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));

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

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

最新更新