Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managing fragment transactions where you don't want to lose data for some fragments

I have 5 fragments, two of which are List Fragments that contains some data(expensive loading) and the rest of them don't have anything important.

My goal is to some how manage the transactions so that only one List fragment remains in memory(at all times) and when I press back it should revert back to the list fragment. This is some partial code that handles this for the on of the fragments but the problem is when I press back it doesn't unload the current fragment rather load the Main Fragment without removing the current fragment.

WorkFlow: Main Fragment(Tasks Fragment) is loaded on start afterwards any fragment can be loaded. if main fragment is current and group fragment is selected then remove main fragment otherwise if any other fragment is selected then retain(hide) the main fragment and load the new fragment

Note: Its is used with Navigation Drawer where 1 fragment is loaded at start

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);
    }

}
like image 761
Abdullah Saleem Avatar asked Nov 08 '22 01:11

Abdullah Saleem


1 Answers

You should not add/remove all fragment by you own, manually I mean. You're using backstack already. You could only add/hide (in case you need to keep 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: Performing Fragment Transactions

like image 156
Sviatoslav Melnychenko Avatar answered Nov 15 '22 07:11

Sviatoslav Melnychenko