How to save state of Fragment having listview

守給你的承諾、 提交于 2019-12-04 02:13:53
alex

As explained here you can use onSaveInstanceState() to save data in the Bundle and retrieve that data in the onRestoreInstanceState() method.

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.

So a good way for you could be to save the scrollposition in onSaveInstanceState() and restore it in onRestoreInstanceState() like this:

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().

This is because (I think) the fragment that is added to the backstack lost its View and then it has to recreate the view. onCreateView() get called and incidentally recreate your adapter.

you can save define your ui in oncreate. when in onCreateView, only add it the layout. so the view state can save perfect.

this is my sv:

in 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

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(). And when you go back, you can fetch that position and restore it to ListView, do that for example in fragment B's onStart(). The position data maybe saved at the Activity so it won't be lost even the fragment detached.

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. So if you restore your position before the framework do that, the framework's restore data will override yours.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!