Я хочу предложить альтернативное решение для, возможно, немного другого случая, так как многие из моих поисков ответов продолжали вести меня к этой теме.
Мой кейс
- Я создаю / добавляю страницы динамически и помещаю их в ViewPager, но при повороте (onConfigurationChange) я получаю новую страницу, потому что, конечно, OnCreate вызывается снова. Но я хочу сохранить ссылку на все страницы, которые были созданы до ротации.
Задача
- У меня нет уникальных идентификаторов для каждого фрагмента, который я создаю, поэтому единственный способ ссылки был каким-то образом хранить ссылки в массиве, который будет восстановлен после изменения ротации / конфигурации.
Обход
- Ключевая концепция заключалась в том, чтобы Activity (которая отображает фрагменты) также управляла массивом ссылок на существующие фрагменты, поскольку это действие может использовать Bundles в onSaveInstanceState
public class MainActivity extends FragmentActivity
Итак, в рамках этого занятия я объявляю частного участника для отслеживания открытых страниц
private List<Fragment> retainedPages = new ArrayList<Fragment>();
Это обновляется каждый раз, когда onSaveInstanceState вызывается и восстанавливается в onCreate
@Override
protected void onSaveInstanceState(Bundle outState) {
retainedPages = _adapter.exportList();
outState.putSerializable("retainedPages", (Serializable) retainedPages);
super.onSaveInstanceState(outState);
}
... так что, как только он будет сохранен, его можно получить ...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
retainedPages = (List<Fragment>) savedInstanceState.getSerializable("retainedPages");
}
_mViewPager = (CustomViewPager) findViewById(R.id.viewPager);
_adapter = new ViewPagerAdapter(getApplicationContext(), getSupportFragmentManager());
if (retainedPages.size() > 0) {
_adapter.importList(retainedPages);
}
_mViewPager.setAdapter(_adapter);
_mViewPager.setCurrentItem(_adapter.getCount()-1);
}
Это были необходимые изменения в основном действии, и поэтому мне понадобились члены и методы в моем FragmentPagerAdapter, чтобы это работало, поэтому в
public class ViewPagerAdapter extends FragmentPagerAdapter
идентичная конструкция (как показано выше в MainActivity)
private List<Fragment> _pages = new ArrayList<Fragment>();
и эта синхронизация (как описано выше в onSaveInstanceState) поддерживается специально методами
public List<Fragment> exportList() {
return _pages;
}
public void importList(List<Fragment> savedPages) {
_pages = savedPages;
}
И, наконец, во фрагменте класса
public class CustomFragment extends Fragment
для того, чтобы все это заработало, было сделано два изменения: первое
public class CustomFragment extends Fragment implements Serializable
, а затем добавить это в onCreate, чтобы фрагменты не были уничтожены
setRetainInstance(true);
Я все еще нахожусь в процессе обдумывания фрагментов и жизненного цикла Android, поэтому предостережение здесь может заключаться в избыточности / неэффективности этого метода. Но это работает для меня, и я надеюсь, что может быть полезным для других в случаях, подобных моему.