2

I need to show a DialogFragment every time the user enter the Activity, so the best callback method would be onResume(). Thing is I can't just call DialogFragment#show() cause it will throw some IllegalStateException, so I did this:

@Override
protected void onResume() {
    super.onResume();

    if(!dialog.isVisible()) {
        dialog.show(getSupportFragmentManager(), "login-dialog");
    }
}

@Override
protected void onPause() {
    super.onPause();

    if(dialog.isVisible()) {
        dialog.dismiss();
    }
}

I'm getting:

java.lang.IllegalStateException: Fragment already added: LoginDialog{41fac3e0 #0 login-dialog}
Sufian
  • 6,405
  • 16
  • 66
  • 120
Christopher Francisco
  • 15,672
  • 28
  • 94
  • 206

2 Answers2

3

I had exactly the same exception and message while trying to keep a DialogFragment visible and working between screen rotations (orientation change). Are your fragments from the support library?

In my case, I was using the support library and the call to dialog.show() was in the activity's onCreate(). What seems to have solved the problem was the workaround presented here:

https://stackoverflow.com/a/14016339/3577211

Which basically is putting setRetainInstance(true) in your DialogFragment's onCreate(). The second part, that is, overriding its onDestroy, was the only way I have managed to make the DialogFragment not go away during screen rotations (and come back when rotating again), even though they say the latest support library versions took care of that (perhaps I have a mess with the jars in here).

You did not state whether you get the exception always or it works only the first time the activity is created. But what I guess is happening is that dialog.show() is actually a wrapper for a getFragmentManager().add() call, which probably checks whether setRetainInstance is true for the dialog and if it is false, the DialogFragment instance is added again to the same FragmentManager instance, which throws that exception.

Yet another suggestion would be not to use onResume() for that; instead use onCreate() and onSaveInstanceState(Bundle outState) with some kind of flag, since that way you can save data across activity cycles (and unless your dialog is just a popup constant message, which is very annoying to have every time the user hits onResume(), you probably have some data to interact with the user that could be lost in unexpected situations).

Community
  • 1
  • 1
0

change !dialog.isVisible() to !dialog.isAdded()

Peter
  • 1