learner
learner

Reputation: 11780

When do Fragments have non-empty savedInstanceState

I have a Fragment inside a ViewPager. The Fragment contains a RecyclerView (think ListView). When the user pages away and then returns to the fragment, no matter where the user left the list, the list always restarts at the top. So I need to retain the currPosition somehow. Would savedInstanceState be a good place to store it? If yes, in which callback do I read the data? Again this is inside a ViewPager and I am using a FragmentPagerAdapter and so not many callbacks are called. Still my broader question stands: What causes a Fragment's savedInstanceState to be non-empty?

To give further breadth to the question. Imagine I have an activity with two fragments. I detach and attach the fragments when needed. Say I navigate away from the activity. Would the savedInstanceState of the fragment be empty in this case if the activity's savedInstanceState is not empty? To be exact here is some code for this second case

private void addMainFragment() {
    
  FragmentManager fm=getSupportFragmentManager();

      FragmentTransaction transaction = fm.beginTransaction();

      Fragment removeFragment = fm.findFragmentByTag(getString(R.string.fragment_a));

      if(null != removeFragment){
    
    transaction.detach(removeFragment);

      }
    
  Fragment fragment = fm.findFragmentByTag(getString(R.string.fragment_b));

      if(null != fragment){

        transaction.attach(fragment);

      }else{
    
    fragment=MainFragment.newInstance(null,null);


 transaction. add(R.id.fragment_container,fragment,getString(R.string.fragment_b)); 
 }

transaction.commit();
 }

Upvotes: 1

Views: 232

Answers (1)

Eoin
Eoin

Reputation: 4066

savedInstanceState is the best place to save information like current postion, selected items etc.

View pagers have an offscreen page limit that handles how many pages (in this case fragments) are kept idle either side of the current visible page. If the page is outside this limit the pages are destroyed. This is to keep memory usage lower. This setting defaults to 1. So when a fragment goes out side this limit and then comes back its savedInstanceState will be non-null.

To answer your second question. Im not quite sure what you mean by navigate away from the activity. If you navigate away from the activity (e.g press the back / home button) then come back. The activities savedInstanceState will be null. If you start another activity on top of the current then onSavedInstance will be called.

Here is a snippet of code I use in one of my projects for restoring a fragments state in a viewpager.

You can override onSaveInstanceState to save some information about the fragment.

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // restore state
    mListState = mLayoutManager.onSaveInstanceState();
    state.putParcelable("list_state", mListState);
}

Then in the fragments onCreateView you can restore the state of the recycelerview

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

    ...

    if (savedInstanceState != null) {
        // save list state
        mListState = state.getParcelable("list_state");
        mLayoutManager.onRestoreInstanceState(mListState);
    }

    return root;
}

Upvotes: 1

Related Questions