GhostDerfel
GhostDerfel

Reputation: 1551

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>

Upvotes: 4

Views: 8839

Answers (3)

emzet
emzet

Reputation: 61

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.

Upvotes: 6

PeterH
PeterH

Reputation: 841

It looks like the first block of code is correct. Can you add the code where you dynamically add the first fragment?

If it just so happens you do that in your onCreateView(), it could be adding it twice. The first one will be correctly replaced, but an older copy that was semi-destroyed when you navigated away and came back by way of the Receiver, will still be shown.

Upvotes: 0

GLee
GLee

Reputation: 5093

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.

Upvotes: 2

Related Questions