ViewPager + FragmentStatePagerAdapter + MvpFragment
See original GitHub issueЗдравствуйте! Пытаюсь использовать ViewPager + FragmentStatePagerAdapter в связке с MvpAppCompatFragment. На первый взгляд работает, но не совсем:) Столкнулся со следующей проблемой. При перелистывании страниц, фрагменты (MvpAppCompatFragment) разрушаются как им и положено, но презентер никогда (onDestroy презентера не вызывается). Покопался в коде. Насколько понял, ноги растут отсюда.
public class MvpAppCompatFragment extends Fragment {
private boolean mIsStateSaved;
...
@Override
public void onDestroy() {
super.onDestroy();
...
!!!!!!!!!! Вот здесь mIsStateSaved = true, и происходит возврат из метода
// When we rotate device isRemoving() return true for fragment placed in backstack
// http://stackoverflow.com/questions/34649126/fragment-back-stack-and-isremoving
if (mIsStateSaved) {
mIsStateSaved = false;
return;
}
mIsStateSaved оказывается равным true, т.к при смене активной страницы фрагмент не разрушается, но вызывается onSaveInstanceState. Разрушение фрагмента происходит только при выдавливании его из стека, но mIsStateSaved = true, соответственно презентер остается живым.
Это мое видение причин проблеммы, может ошибаюсь, поправьте. Дальше опишу к чему это приводит.
Здесь, кроме утечки памяти, ViewPager работает как бы правильно. Если же динамически удалять страницы, то начинаются непонятки. Для чистоты эксперимента в адаптере определил
...
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Fragment getItem(int position) {
return DataCardFragment.newInstance(idModule, idItem, items.get(position), position);
}
...
т.е. при вызове notifyDataSetChanged() все фрагменты пересоздаются. Но презентеры заново не создаются, а цепляются “старые”. Соответственно контент на страницах не соответствует тому что должно.
Сейчас решил проблему так:
@InjectPresenter(type = PresenterType.LOCAL)
DataCardPresenter mDataCardPresenter;
@ProvidePresenterTag(presenterClass = DataCardPresenter.class, type = PresenterType.LOCAL)
String provideRepositoryPresenterTag() {
return TAG + "_" + getArguments().getLong(ARG_IDMODULE) + "_" + getArguments().getLong(ARG_IDITEM) + "_" + getArguments().getLong(ARG_ID);
}
@ProvidePresenter(type = PresenterType.LOCAL)
DataCardPresenter provideDataCardPresenter() {
return new DataCardPresenter((DataCardMode) getArguments().getSerializable(ARG_MODE), getArguments().getLong(ARG_IDMODULE), getArguments().getLong(ARG_IDITEM), getArguments().getLong(ARG_ID), getArguments().getInt(ARG_POS), _dataJson);
}
Работает правильно, но презентеры все равно не разрушаются.
Полагаю имеет место ошибка в библиотеке. Что посоветуете? Склонюсь сделать реализацию MvpFragment для ViewPager. Может что подскажете, а то одно исправлю, другое сломаю.😃
Самый простой вариант решения переопределить FragmentStatePagerAdapter.destroyItem и устанавливать там ((MvpAppCompatFragment)fragment).mIsStateSaved = false,. Или просто вызывать там ((MvpAppCompatFragment)fragment).getMvpDelegate().onDestroy(); Как лучше?
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:6
В итоге я взял за основу https://github.com/inloop/UpdatableFragmentStatePagerAdapter/blob/master/library/src/main/java/eu/inloop/pager/UpdatableFragmentPagerAdapter.java Немного допилил (добавил отключение сохранения состояния), заработало как нужно. Если нужно могу “допиленный” адаптер дать.
Спасибо!