I'm studying MVP.
I have and activity with nav menu and I change fragments from menu like this:
switch (id) {
case R.id.nav_status:
fragmentManager.beginTransaction().replace(R.id.fr_main, mAppProductFragment).commit();
Log.d(TAG, "Выбрано меню статус");
break;
case R.id.nav_schemas:
AppRedirectFragment schemasFragment = new AppRedirectFragment();
fragmentManager.beginTransaction().replace(R.id.fr_main, schemasFragment).commit();
Log.d(TAG, "Выбрано меню переадресация");
break;
}
The problem is that when I change the fragment, my previous fragment is destroyed. It calls the following callbacks:
D/AppProductPresenter: onStopDetouchView()
D/AppProductFragment: onDestroyView
D/AppProductFragment: onDestroy()
It loses its reference to the presenter and also dsipose all retrofit requests.
mPresenter.onDestroyView();, so all my network operations are destroyd. But Id like to run them in backgroud. But its disposed.
public void onDestroy() {
super.onDestroy();
mPresenter.onDestroyView();
}
So how can change fragments without calling onDestroy being called? I read that I have to use add instead of fragmentManager.beginTransaction().replace
So how do it correctly?
When you use
fragmentManager
.beginTransaction()
.replace(R.id.fr_main, schemasFragment)
//addToBackstack(String name) //if you want to keep transaction to backstack
.commit();
replace() will remove previous fragment and add new one, so you cant avoid onDestroy(). But when you call
fragmentManager
.beginTransaction()
.add(R.id.fr_main, schemasFragment)
//addToBackstack(String name) //if you want to keep transaction to backstack
.commit();
you just add new fragment over previous one and previous fragment will still exist. But if you will add a lot of fragments without removing previous - your app can become sluggish. If your retrofit requests are complex - good decision is to do it in services.
I solve a problem.
The answer is use combo of: .add .attach and .detach methods. I create a function that replace a fragmetns like this:
switch (id) {
case R.id.nav_product:
replaceFragment(PRODUCT_FRAGMENT);
break;
case R.id.nav_redirection:
replaceFragment(REDIRECTION_FRAGMENT);
break;
}
private void replaceFragment(String tag) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment currentFragment = fragmentManager.findFragmentById(R.id.fr_container);
Fragment nextFragment = fragmentManager.findFragmentByTag(tag);
Log.d(TAG, "f detached: " + currentFragment.toString());
transaction.detach(currentFragment);
if (nextFragment == null) {
nextFragment = createFragment(tag);
transaction.add(R.id.fr_container, nextFragment, tag);
} else {
Log.d(TAG, "f attach: " + nextFragment.toString());
transaction.attach(nextFragment);
}
transaction.commit();
}
private Fragment createFragment(String tag) {
Fragment result = null;
switch (tag) {
case CALLHISTORY_FRAGMENT:
result = new AppCallHistoryFragment();
break;
case CALLTRACKING_FRAGMENT:
result = new AppCallTrackingFragment();
break;
case REDIRECTION_FRAGMENT:
result = new AppRedirectFragment();
break;
}
Log.d(TAG, "create: " + result.toString());
return result;
}
Now its ok. Fragments are Destroyed only when Activity is destroying.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With