Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recovering presenters for the ViewPager fragments (MVP)

I'm trying to refactor an existing application to use the MVP architecture. One of the activities has a ViewPager with three fragments. Each fragment is linked with a presenter. To be precise - each presenter, when created, is given a View to work with, i.e. a Fragment. For now, I'm creating these presenters inside the ViewPager's adapter - specifically in the getItem(int position) method.

Fragment fragment = FirstFragment.newInstance();
FirstPresenter presenter = new FirstPresenter(repo, (FirstContract.View) fragment, projectId, userId);

The problem I'm facing is if the process is killed and then restarted, ViewPager has its own lifecycle and therefore getItem is not called again - the fragments are recreated automagically with no presenters.

Is there a known solution to this problem?

like image 825
vkislicins Avatar asked Feb 14 '17 10:02

vkislicins


1 Answers

As there's still no ideal answer to this question, I thought it might be good to share my interim solution.

As I've mentioned in one of the comments, the goal here is to recover ViewPager from process kill and ideally keep the Presenter initialisation decoupled from the View. For now, my solution is to override restoreState(Parcelable state, ClassLoader loader) inside the FragmentStatePagerAdapter, inspect the state Parcelable similar to the actual implementation of the restoreState method, then for each fragment of a certain class, I can initialise a presenter and assign it a view.

@Override
public void restoreState(Parcelable state, ClassLoader loader) {
    if (state != null) {
        Bundle bundle = (Bundle)state;
        bundle.setClassLoader(loader);
        Iterable<String> keys = bundle.keySet();
        for (String key: keys) {
            if (key.startsWith("f")) {
                Fragment f = mFragmentManager.getFragment(bundle, key);
                if (f != null) {
                    if (f instanceof FirstFragment) {
                       new FirstPresenter(repo, (FirstContract.View) f, projectId, userId);
                    }
                } else {
                    Log.w(TAG, ".restoreState() - bad fragment at key " + key);
                }
            }
        }
    }

    super.restoreState(state, loader);
}
like image 78
vkislicins Avatar answered Sep 24 '22 02:09

vkislicins