How to save state of Fragment having listview
Asked Answered
P

4

12

Here is a situation. I want to navigate from Fragment A-> B-> C.

In B Fragment there is listview. On item click I open the detail view 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.

All goes well. But when I return to B from C, the view is being refreshed and hence the webservice is being called again. I don't want to do this. I want to retain the B Fragment state with listview.

I got some post of Retain Instance, but it didn't help that much.

Any help is much appreciated.

Thanks.

Porphyroid answered 23/7, 2013 at 12:53 Comment(3)
Have you looked into using the Bundle and Overriding onSavedInstance()?Annamarieannamese
Hi @dakshbhatt21 ,did you get a solution for your problem??I have the same problem,it has been bugging me for a week with no breakthrough.Yusem
hi @mungaihkamau please check this articles developer.android.com/training/implementing-navigation/… , you can find various types of navigation when working with fragments, just check it out and let me know.Worked
P
13

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.

Palstave answered 23/7, 2013 at 13:27 Comment(2)
@Palstave It's not working for me. I've listview in search button(bottom bar button). My listview will be recreated when I click the below search button. I can't save the state of the listview. Help me..Eighty
Can you please post your xml layout and show your code. It might be better to start a new question, to do so and link this question thread as "similar"Palstave
C
2

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.

Contravention answered 31/12, 2015 at 15:36 Comment(0)
I
0

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));
Ifc answered 8/11, 2013 at 13:29 Comment(0)
S
0

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.

Selfmortification answered 25/12, 2013 at 14:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.