0

Can someone explain me why replacing fragment on thread causes sometimes blank space instead of showing the fragment on screen?

public void swapFragment(final CustomFragment fragment) {

    new Thread(new Runnable() {
        @Override
        public void run() {
            FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
            ft.replace(R.id.fragment_container, fragment, fragment.getName());
            ft.addToBackStack(fragment.getName());

            ft.commit();
        }
    }).start();

}

Let me explain what is happening:

1) I have no fragment added inside my container.

2) I'm adding fragment A using this method - its working

3) Then I'm using this method to swap actual fragment A with my fragment B - its working

4) But when I'm trying to swap it with new instance (!!!) of fragment A it leaves blank space

I know that i can do it on main thread, but this is just an example. I'm dealing with different issue, but my issue is more complex to explain.

EDIT :

at point 4) I placed wrong fragment - it was ment to be "fragment A"

Lau
  • 1,804
  • 1
  • 23
  • 49

1 Answers1

2

You are swapping same Fragment B with its new instance.

Swapping operation will work only when source and destination fragments are of different classes.

I can defer this from answers this and question this

So, workaround would be :

  1. Check if same fragment class is already added (isAdded()) or not, if not then swap() else use remove() and add() operation

    public void swapFragment(final CustomFragment fragment) {
    
    new Thread(new Runnable() {
        @Override
        public void run() {
            FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
            if(!fragment.isAdded()) {
                ft.replace(R.id.fragment_container, fragment, fragment.getName());
                ft.addToBackStack(fragment.getName());
    
                ft.commitAllowingStateLoss();
    
            } else {
                ft.remove(R.id.fragment_container, fragment);
                ft.add(fragment);
                ft.addToBackStack(fragment.getName());
    
                ft.commitAllowingStateLoss();
    
        }
    }).start();
    

    }

  2. Check if same fragment class is already added (isAdded()) then update its UI content, else swap()

    public void swapFragment(final CustomFragment fragment) {
    
    new Thread(new Runnable() {
        @Override
        public void run() {
             FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
            if(!fragment.isAdded()) {
                ft.replace(R.id.fragment_container, fragment, fragment.getName());
                ft.addToBackStack(fragment.getName());
    
                ft.commitAllowingStateLoss();
            } else {
                // logic to update UI of same instance
            }
        }
    }).start();
    

    }

Still, exact solution is awaited for this question :)

Hope this will help you

Community
  • 1
  • 1
Kushal
  • 8,100
  • 9
  • 63
  • 82