简体   繁体   中英

Retaining the instance state of Fragments in Fragment Pager Adapter

I'm having a frustrating problem. I'm able to create each fragment that the pager adapter handles, and I'm able to swipe-right to view all of them; however, upon swiping left, the fragments are either gone or just duplicates of the one I was already looking at. I googled around, and couldn't find much, which is confusing as the API for the FragmentPagerAdapter says that it keeps each fragment in memory. I'll be displaying a max of like 20 fragments, so memory isn't an issue. Anyway, here's my code, and I appreciate any feedback you can give; it's still in like pre-alpha stage.

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_events_screen);

    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    SectionsPagerAdapter adapter = new         SectionsPagerAdapter(getFragmentManager());

    // Set up the ViewPager with the sections adapter.
    ViewPager pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);
}

 /**
  * TEMPORARY
  */
public void onBackPressed() {
    finish();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.events_screen, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the page.
        // Return a PlaceholderFragment (defined as a static inner class
        // below).
        return EventFragment.newInstance(position + 1);
    }

    /**
     * Total number of pages (fragments) there are
     * Given by size of the array returned by Service.getEvents()
     */
    @Override
    public int getCount() {
        return connection.getEvents().size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return null;
    }
}

/**
 * The fragment holding the text for each event.
 */
public static class EventFragment extends Fragment {

    static int index;

    /**
     * Returns a new instance of this fragment for the given section number.
     */
    public static EventFragment newInstance(int sectionNumber) {
        index = sectionNumber;
        EventFragment fragment = new EventFragment();
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_events_screen, container, false);
        TextView textView = (TextView) rootView.findViewById(R.id.section_label);
        textView.setText(connection.getEvents().get(index - 1));
        return rootView;
    }
}

Yes you are right fragments are kept in memory but it will used large amount of memory thus giving not expected result you want as the documentation is saying:

The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider FragmentStatePagerAdapter.

The FragmentStatePagerAdapter is the one you are looking for if you want to have a lot of page/fragments in the adapter.

Upon using the FragmentStatePagerAdapter, I was able to fix two problems:

1) Duplicate fragments that frustratingly disappeared when I swiped right and left. This was due to getItem() calling twice for the same fragment due to EventFragment.newInstance(position + 1).

2) Save the instance state of fragments so that I could continually swipe left and right without coming upon a blank page.

Thanks for your help, @Rod_Algonquin. Saved me hours of stress.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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