Skip to content Skip to sidebar Skip to footer

Android Using Both Getfragmentmanager And Getsupportfragmentmanager Causes Overlapping

I have something like this inside my activity: @Override public void onNavigationDrawerItemSelected(int position) { Fragment fragment = null; switch (position+1

Solution 1:

I have accomplished something like this when using PreferenceFragment (not supported by support library version). In order to achieve this I kept inside my Activity a pair of boolean (isLastFragmentSupportType and lastFragmentShowed) and also a String (lastFragmentTag).

At the beginning your Activity will have both of them to false. And when you add a new Fragment you use these 2 boolean to know if you need to clean the other FragmentManager or not. I'll use your code as an example:

@OverridepublicvoidonNavigationDrawerItemSelected(int position) {
    Fragmentfragment=null;
    switch (position+1) {
        case1: {
            if(isLastFragmentSupportType && lastFragmentShowed)
            {//As your last fragment  was a support type you need to clear your supportFragmentManager
              android.support.v4.app.Fragmentfr_v4= getSupportFragmentManager().findFragmentByTag(lastFragmentTag);
               getSupportFragmentManager().beginTransaction().remove(fr_v4).commit();
            }
            fragment = newFragment_Login();
            FragmentManagerfrgManager= getFragmentManager();
            frgManager.beginTransaction().replace(R.id.container, fragment,TAG1)
                    .commit();
          lastFragmentTag = TAG1;
          lastFragmentShowed = true;
          isLastFragmentSupportType = false; 
            break;
        }
       //And so on with the others

You need to check what type (support or not) of fragment you are going to use, and check these variables to see if the last fragment was of a different type. If that is the case clean the other fragmentmanager to "clear" the screen so they wont overlap.

Also use TAGS to identify and retrieve your current fragments so you do not need to have Fragment variables over your code.

Finally use onSavedInstanceState so as to keep these values in case you need them.

Hope it helps :)

Solution 2:

This answer is inspired from answer by zozelfelfo. Use these two methods to replace fragments instead of getFragmentManager.beginTransaction.replace...

privatevoidreplaceFragment(Fragment fragment, String fragmentTag) {
    if(lastFragmentShowed && isLastFragmentSupportType) {
        android.support.v4.app.Fragment fr_v4 = getSupportFragmentManager().findFragmentByTag(lastFragmentTag);
        getSupportFragmentManager().beginTransaction().remove(fr_v4).commit();
    }
    getFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, fragment, fragmentTag)
            .commit();
    lastFragmentTag = fragmentTag;
    lastFragmentShowed = true;
    isLastFragmentSupportType = false;
}

privatevoidreplaceFragment(android.support.v4.app.Fragment fragment, String fragmentTag) {
    if(lastFragmentShowed && !isLastFragmentSupportType) {
        Fragment fr = getFragmentManager().findFragmentByTag(lastFragmentTag);
        getFragmentManager().beginTransaction().remove(fr).commit();
    }
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, fragment, fragmentTag)
            .commit();
    lastFragmentTag = fragmentTag;
    lastFragmentShowed = true;
    isLastFragmentSupportType = true;
}

Solution 3:

I'm using BottomNavigationView as Tab Bar and switching fragments as tabs. All but one fragment are Support Fragments (and last one is PreferenceFragment). I'm using "hide-add-show" rather than "remove-replace". So, status of fragments in other tabs can be preserved.

Original function to switch:

privateFragmentlastFragment=null;
privatevoidswitchFragment(Fragment fragment) {
    if (lastFragment != fragment) {
        FragmentTransactiontransaction= getSupportFragmentManager().beginTransaction();
        if (null != lastFragment) {
            transaction.hide(lastFragment);
        }
        lastFragment = fragment;
        if (!fragment.isAdded()) {
            transaction.add(R.id.fragment_container, fragment);
        }
        transaction.show(fragment).commitAllowingStateLoss();
    }
}

I don't use tag nor boolean, just want to keep a reference to last fragment object. So, when switching, just call switchFragment() with instance of any fragment:

privateObject lastFragment = null;
privatevoidswitchFragment(Object fragment) {
    if (lastFragment != fragment) {
        if (null != lastFragment) {
            if (lastFragment instanceof android.support.v4.app.Fragment) {
                hideFragment((android.support.v4.app.Fragment) lastFragment);
            } elseif (lastFragment instanceof android.app.Fragment) {
                hideFragment((android.app.Fragment) lastFragment);
            }
        }
        lastFragment = fragment;
        if (fragment instanceof android.support.v4.app.Fragment) {
            showFragment((android.support.v4.app.Fragment) fragment);
        } elseif (fragment instanceof android.app.Fragment) {
            showFragment((android.app.Fragment) fragment);
        }
    }
}

So, this function still do the same things but switch between Support Fragment and Native Fragment by checking the target class. Helper functions:

// Support Version:privatevoidhideFragment(android.support.v4.app.Fragment fragment) {
    getSupportFragmentManager().beginTransaction().hide(fragment).commit();
}

privatevoidshowFragment(android.support.v4.app.Fragment fragment) {
    android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    if (!fragment.isAdded()) {
        transaction.add(R.id.fragment_container, fragment);
    }
    transaction.show(fragment).commitAllowingStateLoss();
}

// Native Version:privatevoidhideFragment(android.app.Fragment fragment) {
    getFragmentManager().beginTransaction().hide(fragment).commit();
}

privatevoidshowFragment(android.app.Fragment fragment) {
    android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
    if (!fragment.isAdded()) {
        transaction.add(R.id.fragment_container, fragment);
    }
    transaction.show(fragment).commitAllowingStateLoss();
}

To avoid confusion, I removed the import so classes require full names.

Post a Comment for "Android Using Both Getfragmentmanager And Getsupportfragmentmanager Causes Overlapping"