简体   繁体   English

如何保存具有listview的Fragment状态

[英]How to save state of Fragment having listview

Here is a situation. 这是一种情况。 I want to navigate from Fragment A-> B-> C. 我想从Fragment A-> B-> C导航。

In B Fragment there is listview. 在B片段中有listview。 On item click I open the detail view C Fragment. 单击项目时,打开详细视图C Fragment。 Ofcourse I used replace method and added addtoBackStack(null) while transactiong from B to C so that on Back press it returned to B. 当然我使用了替换方法并添加了addtoBackStack(null),而事务从B到C,所以在Back上按下它返回到B.

All goes well. 一切顺利。 But when I return to B from C, the view is being refreshed and hence the webservice is being called again. 但是当我从C返回B时,视图正在刷新,因此再次调用web服务。 I don't want to do this. 我不想这样做。 I want to retain the B Fragment state with listview. 我想用listview保留B Fragment状态。

I got some post of Retain Instance, but it didn't help that much. 我得到了一些Retain Instance的帖子,但它并没有那么多帮助。

Any help is much appreciated. 任何帮助深表感谢。

Thanks. 谢谢。

As explained here you can use onSaveInstanceState() to save data in the Bundle and retrieve that data in the onRestoreInstanceState() method. 如此处所述您可以使用onSaveInstanceState()将数据保存在Bundle中,并在onRestoreInstanceState()方法中检索该数据。

Often setRetainState(true) is mentioned as way to keep the ui state in fragment, but it does not work for you because you are using the backstack. 通常提到setRetainState(true)作为将ui状态保持在片段中的方式,但它不适合您,因为您正在使用backstack。

So a good way for you could be to save the scrollposition in onSaveInstanceState() and restore it in onRestoreInstanceState() like this: 所以一个好方法可能是将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);
  }

}

Further more you can find a more detailed similiar example here . 您还可以在此处找到更详细的类似示例。

I have solved this problem by creating my Adapter on onCreate() instead of onCreateView(). 我通过在onCreate()而不是onCreateView()上创建我的适配器来解决这个问题。

This is because (I think) the fragment that is added to the backstack lost its View and then it has to recreate the view. 这是因为(我认为)添加到backstack的片段丢失了它的View,然后它必须重新创建视图。 onCreateView() get called and incidentally recreate your adapter. 调用onCreateView()并顺便重新创建适配器。

you can save define your ui in oncreate. 你可以保存在oncreate中定义你的ui。 when in onCreateView, only add it the layout. 在onCreateView中,只添加布局。 so the view state can save perfect. 所以视图状态可以保存完美。

this is my sv: 这是我的sv:

in oncreate 在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);

strong text in onCreateView 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));

I think you can save your ListView's position just before you're leaving fragment B. Maybe do that in fragment B's onStop() . 我想你可以在离开片段B之前保存ListView的位置。也许在片段B的onStop()中这样做 And when you go back, you can fetch that position and restore it to ListView, do that for example in fragment B's onStart() . 当你回去时,你可以获取该位置并将其恢复到ListView,例如在片段B的onStart()中执行此操作 The position data maybe saved at the Activity so it won't be lost even the fragment detached. 位置数据可能保存在Activity中,因此即使片段分离也不会丢失。

One thing should be noticed that(I've been trapped by this), if the saved position data is updated by the background service, you should avoid restoring it to ListView before the life-cycle stage onStart() of fragment B, because actually, the framework will save the view's state just before leaving the fragment and restore it when get back. 有一点需要注意(我已经被这个困住了),如果保存的位置数据由后台服务更新,你应该避免在片段B的生命周期阶段onStart()之前将它恢复到ListView,因为实际上,框架将在离开片段之前保存视图的状态,并在返回时恢复它。 So if you restore your position before the framework do that, the framework's restore data will override yours. 因此,如果您在框架之前恢复您的位置,框架的恢复数据将覆盖您的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM