Transaction management of fragments in which you do not want to lose data for some fragments

I have 5 fragments, two of which are fragments of the list containing some data (expensive loading), and the rest of them have nothing important.

My goal is how to manage transactions so that only one fragment of the list remains in memory (always), and when I click, it should return to the fragment of the list. This is some partial code that processes this to include fragments, but the problem is that when I click back, it does not unload the current fragment, but loads the main fragment without deleting the current fragment.

WorkFlow: The main fragment (Task fragment) is loaded at startup, after which any fragment can be loaded. if the main fragment is current, and the group fragment is selected, then delete the main fragment, otherwise, if any other fragment is selected, then save (hide) the main fragment and load a new fragment

Note. It is used with a navigation box, where 1 fragment is loaded at startup

public class FragmentController { private static final String TAG_MAIN = "main"; //Expensive private static final String TAG_GROUP = "group"; //Expensive private static final String TAG_PROFILE = "profile"; //Cheap private static final String TAG_CREATE_TASK = "create_task"; //Cheap private static final String TAG_CREATE_GROUP = "create_group";//Cheap private static final String TAG_SETTINGS = "settings"; //Cheap private android.support.v4.app.FragmentManager fragmentManager; @IdRes private int container; public FragmentController(android.support.v4.app.FragmentManager fragmentManager, @IdRes int container) { this.fragmentManager = fragmentManager; this.container = container; } public void showMainFragment() { FragmentTransaction transaction = fragmentManager.beginTransaction(); if (containsMainFragment()) { if (!isMainCurrent()) { transaction .show(getMainFragment()) .commit(); } } else { transaction .replace(container, getMainFragment(), TAG_MAIN) .commit(); } } public void showGroupFragment() { FragmentTransaction transaction = fragmentManager.beginTransaction(); if (containsGroupFragment()) { if (!isGroupCurrent()) { transaction .show(getGroupFragment()) .commit(); } } else { transaction .replace(container, getGroupFragment(), TAG_GROUP) .commit(); } } public void showProfileFragment() { showLightFragment(ProfileFragment.newInstance(), TAG_PROFILE); } public void showCreateTaskFragment() { showLightFragment(CreateTaskFragment.newInstance(), TAG_CREATE_TASK); } public void showCreateGroupFragment() { showLightFragment(CreateGroupFragment.newInstance(), TAG_CREATE_GROUP); } public void showSettingsFragment() { showLightFragment(SettingsFragment.newInstance(), TAG_SETTINGS); } private void showLightFragment(Fragment fragmentInstance, String tag) { FragmentTransaction transaction = fragmentManager.beginTransaction(); Fragment fragment = getCurrentFragment(); if (containsListFragment() && (isMainCurrent() || isGroupCurrent())) { assert fragment != null; transaction = transaction .hide(fragment) .add(container, fragmentInstance, tag) .addToBackStack(tag); } else { transaction = transaction .remove(fragment) .add(container, fragmentInstance, tag); } if(isCreateTaskFragment(fragment)){ transaction = transaction .addToBackStack(tag); } transaction.commit(); } private boolean containsListFragment() { return getFragmentByTag(TAG_MAIN) != null || getFragmentByTag(TAG_GROUP) != null; } private boolean containsMainFragment() { return getFragmentByTag(TAG_MAIN) != null; } private boolean containsGroupFragment() { return getFragmentByTag(TAG_GROUP) != null; } private Fragment getMainFragment() { Fragment fragment = getFragmentByTag(TAG_MAIN); if (fragment == null) { fragment = TasksFragment.newInstance(); } return fragment; } private Fragment getGroupFragment() { Fragment fragment = getFragmentByTag(TAG_GROUP); if (fragment == null) { fragment = GroupTasksFragment.newInstance(); } return fragment; } private Fragment getFragmentByTag(String tag) { return fragmentManager.findFragmentByTag(tag); } private Fragment getCurrentFragment() { return fragmentManager.findFragmentById(container); } private boolean isMainCurrent() { return isCurrent(TAG_MAIN); } private boolean isGroupCurrent() { return isCurrent(TAG_GROUP); } private boolean isCurrent(String tag) { Fragment fragment = getCurrentFragment(); return fragment != null && fragment.getTag() != null && fragment.getTag().equals(tag); } private boolean isCreateTaskFragment(Fragment fragment){ return fragment!=null && fragment.getTag()!=null && fragment.getTag().equals(TAG_CREATE_TASK); } } 
+5
source share
2 answers

Well, the problem remains, but I ended up replacing CreateTaskFragment (which was the problem) with activity.

0
source

You do not have to add / remove the entire fragment yourself, I mean. You are already using backstack. You can add / hide (if you need to save the previous fragment) or replace. Then activity will do everything for you with

 @Override public void onBackPressed() { if (getSupportFragmentManager().getBackStackEntryCount() > 0) { getSupportFragmentManager().popBackStack(); } else { super.onBackPressed(); } } 

See details here: Fragment Transaction Execution

+1
source

Source: https://habr.com/ru/post/1264196/


All Articles