question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:6

github_iconTop GitHub Comments

2reactions
DmitryMtvcommented, Jan 25, 2019

В итоге я взял за основу https://github.com/inloop/UpdatableFragmentStatePagerAdapter/blob/master/library/src/main/java/eu/inloop/pager/UpdatableFragmentPagerAdapter.java Немного допилил (добавил отключение сохранения состояния), заработало как нужно. Если нужно могу “допиленный” адаптер дать.

0reactions
mancjcommented, Jan 28, 2019

Спасибо!

Read more comments on GitHub >

github_iconTop Results From Across the Web

ViewPager with FragmentPagerAdapter - CodePath Cliffnotes
Overview. Layout that allows the user to swipe left and right through "pages" of content which are usually different fragments. This is a...
Read more >
Mosby MVP - FragmentStatePagerAdapter - NPE
My working activity use the FragmenPagerAdapter. The new Activity should use FragmenStatePagerAdapter. At this point i get a NPE. Here is my ...
Read more >
Are there problems with FragmentStatePagerAdapter? #103
Hi again, I have added another example for ViewPager (in sample) with and without FragmentStatePagerAdapter ():. Everything works as expected ..
Read more >
Slide between fragments using ViewPager - Android Developers
Creates a class that extends the FragmentStatePagerAdapter abstract class and implements the getItem() method to supply instances of ...
Read more >
Fragments in ViewPager - Michał Łuszczuk
Using ViewPager with FragmentPagerAdapter or FragmentStatePagerAdapter appears to be quite easy and enjoyable. It could be done within few simple steps:.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found