Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FragmentTransaction replace not working

I already searched for this issue on stackoverflow and found this two solutions:

Replacing a fragment with another fragment inside activity group
Fragment add or replace not working

But my code seems to be correct as you can check below, the comments on my code are in Portugues (Brazil):

This is my class MenuItemReceiver (Yes, I use a BroadcastReceiver to show my fragments), this already work to show my fragment content but when I try to replace it, the old fragment stays and the new one just appear above the old one.

    public void onReceive(Context context, Intent intent) {
        //Fragment que será carregado, este fragment foi repassado pelo SlideMenuAdapter ao ter um item clicado
        Serializable serializableExtra = intent.getSerializableExtra(CustomFragment.CUSTOM_FRAGMENT);
        //Cast para CustomFragment uma vez que devemos recupera-lo como Serializable, poderia ter dado cast direto, mas decidi manter assim para melhor entendimento do código
        CustomFragment fragment =  (CustomFragment) serializableExtra;
        FragmentTransaction ft = slideMenuActivity.getSupportFragmentManager().beginTransaction();//Informa que estamos inicando uma transação nova
        ft.replace(R.id.dashboard,fragment);
        ft.addToBackStack(null);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.commit();
        //Aplicamos as alterações permitindo que o estado do fragment seja perdido posteriormente, utilizamos o StateLoss para otimizar 
        //o gerenciamento de memória e garantir que nenhum fragment fique para traz porem sem possibilitado de ser "revisitado"
        slideMenuActivity.toggle();//Aqui simplesmente estamos escondendo o menu
    }

I have tried also with this code and have no difference:

    public void onReceive(Context context, Intent intent) {
        Serializable serializableExtra = intent.getSerializableExtra(CustomFragment.CUSTOM_FRAGMENT);
        CustomFragment fragment =  (CustomFragment) serializableExtra;
        Fragment oldFragment = slideMenuActivity.getSupportFragmentManager().findFragmentById(R.id.dashboard);
        FragmentTransaction ft;
        if(oldFragment!=null){
            ft = slideMenuActivity.getSupportFragmentManager().beginTransaction();
            ft.remove(oldFragment);
            ft.commit();
        }
        ft = slideMenuActivity.getSupportFragmentManager().beginTransaction();ft.add(R.id.dashboard,fragment);
        ft.addToBackStack(null);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.commit();
        slideMenuActivity.toggle();
    }

And here you can see my dashboard layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dashboard"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white" >

</FrameLayout>
like image 307
GhostDerfel Avatar asked Feb 14 '23 04:02

GhostDerfel


2 Answers

Please take into account that fragmentTransaction.replace is (at the time of writing this) buggy - see https://code.google.com/p/android/issues/detail?id=24674.

What you could do now is

  • to star the issue (at the link provided) and
  • come up with a workaround until Google has it fixed.

My workaround is to manually remove all relevant fragments (with the help of fragmentManager.getFragments()) and to add the new fragment normally with fragmentTransaction.add.

like image 196
emzet Avatar answered Feb 20 '23 03:02

emzet


It looks like you have an issue with OldFragment. In your second code block, you have slideMenuActivity.getSupportFragmentManager().findFragmentById(R.id.dashboard) which implies that oldFragment = R.id.dashboard, and that it is added in xml. This method has two problems:

  1. You can't replace fragments that are added in xml, you can only replace ones that were added dynamically.
  2. You have to call replace on the container that has the fragment, not the fragment itself. So instead of calling replace(R.id.dashboard, fragment) it should be replace(R.id.dashboards_container, fragment).

Also, if you are toggling between the same fragments, consider using attach and detach instead of replace. Attach and detach only destroy the view hierarchy, while replace destroys them completely. Thus, attach and detach will increase performance if you are trying to reuse the same fragments. See my answer here for an example of attach/detach.

like image 45
GLee Avatar answered Feb 20 '23 02:02

GLee