12

这是一种情况。我想从片段 A-> B-> C 导航。

在 B 片段中有列表视图。在项目上单击我打开详细视图 C 片段。当然,我使用了替换方法并在从 B 到 C 的事务时添加了 addtoBackStack(null),以便在返回时它返回到 B。

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

我得到了一些保留实例的帖子,但它并没有太大帮助。

任何帮助深表感谢。

谢谢。

4

4 回答 4

13

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

经常提到 setRetainState(true) 作为将 ui 状态保持在片段中的方法,但它对您不起作用,因为您正在使用 backstack。

因此,对您来说一个好方法是将滚动位置保存在 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);
  }

}

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

于 2013-07-23T13:27:30.470 回答
2

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

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

于 2015-12-31T15:36:29.153 回答
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));
于 2013-11-08T13:29:07.783 回答
0

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

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

于 2013-12-25T14:04:20.870 回答