11

I am building a navigation drawer as designed by the google documentation however I have an issue where the fragment is not being replaced. http://developer.android.com/training/implementing-navigation/nav-drawer.html

When the app first loads, the default fragment is loaded. Clicking on another item on the drawer list leaves an empty view However on rotating the device, loads the fragment chosen.

public void selectNavActivty(int position){
    // TODO Changing between the different screens selection
    fragment = null;
    switch (position) {
        case 0:
            fragment = OverLay.newInstance();
            break;
        case 1: 
            fragment = Dummy.newInstance();
            break;
        }

    if(fragment != null) {
        // attach added to handle viewpager fragments
        FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
        trans.replace(R.id.content_frame, fragment).attach(fragment)
            .addToBackStack(null);

        trans.commit();
        getFragmentManager().executePendingTransactions();
    } else {
        Log.d("Drawer Activity","Error in creating Fragment");
    }
}
Mike
  • 4,550
  • 4
  • 33
  • 47
androiduae
  • 153
  • 2
  • 9
  • 1
    I have the SAME issue. It is not common. It happens 1 in 20 attempts. onActivityCreated is created, the view can be blank OR part of the view can be blank... I add instead of replacing. – apmartin1991 Jan 12 '16 at 11:11
  • @apmartin1991 can you provide your code snippets somewhere here (as a gist.github.com, for example) - it would be easier to understand the root cause? (in the original post, for example, .attach() is called, but shouldn't and there's no need to call `executePendingTransactions()`, for example, but we don't know anything about your problem. – Konstantin Loginov Jan 12 '16 at 21:47
  • Konstantin Loginov - Here is my question about the same thing http://stackoverflow.com/questions/34742360/fragment-transaction-loads-a-blank-view – apmartin1991 Jan 13 '16 at 09:50
  • @apmartin1991 I've answered there. I think caused by usage of `executePendingTransactions` and adding fragments on top of existing ones, which is bad practice in general, as both of them are keeping in memory and active. – Konstantin Loginov Jan 13 '16 at 17:48

5 Answers5

4

For navigation menu fragment transactions I use the following approach, this way the fragment will be added and placed on top.

String name = "myFragment";
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, fragment, name)
.commit();

Look up the attach() function. It follows a different fragment lifecycle. Also make sure that your layout files framelayout is visible.

Cayce Williams
  • 398
  • 4
  • 8
0

Modify your code as below:

if(fragment != null) {
        // attach added to handle viewpager fragments
        FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
        trans.replace(R.id.content_frame, fragment);
        trans.addToBackStack(null);
        trans.commit();
    } else {
        Log.d("Drawer Activity","Error in creating Fragment");
    }

If the solution doesn't work for you, share the xml code along with your fragment code.

Geeky Singh
  • 1,003
  • 9
  • 20
0

After adding Fragment it will be added to activity state and its view will be added to defined Container view. But by attaching nothing will be displayed if fragment was not already added to UI. It just attaches to fragment manager. However if view was already added to a container in UI and detached after that, by attaching it will be displayed again in its container. Finally you can use attach and detach if you want to destroy fragment View temporarily and want to display and build its view on future without losing its state inside activity.

https://stackoverflow.com/a/18979024/3329488

Community
  • 1
  • 1
Mo1989
  • 2,374
  • 1
  • 15
  • 17
0

My solution is to tag all the fragment with unique tag on fragment replacement. Make sure you also assign a unique tag to the default fragment during it creation. A more efficient way is to identify the fragment before you recreate the same one.

public void selectNavActivty(int position){
// TODO Changing between the different screens selection

    FragmentManager fragmentManager = getSupportFragmentManager();
    fragment = fragmentManager.findFragmentById(R.id.content_frame);
    String fragmentTag = null;
    switch (position) {
        case 0:
            fragmentTag = "case0Tag"; // please change to better tag name
            break;
        case 1: 
            fragmentTag = "case1Tag"; // please change to better tag name
            break;
        default:
            Log.d("Drawer Activity","Error in creating Fragment");
            return;
    }
    if (fragmentTag != null && !fragment.getTag().equals(fragmentTag))
    fragmentManager.beginTransaction().replace(R.id.content_fragment, fragment, tag).commit();
}
Grace Coder
  • 804
  • 11
  • 19
0

In my case after rotating a device a blank fragment was shown. I understood that in an Activity.onCreate() I always called creating a blank Fragment and after that a needed one. So I changed it's behaviour to this:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    if (savedInstanceState == null) {
        openEmptyFragment()
        openAnotherFragment()
    }
}

I recommend to check savedInstanceState != null before adding new fragments, as written in Why won't Fragment retain state when screen is rotated?.

CoolMind
  • 26,736
  • 15
  • 188
  • 224