Proper way of dismissing DialogFragment while application is in background
Asked Answered
A

5

79

I started using DialogFragment, because they are working nicely through orientation changes, and stuff. But there is nasty problem I encountered.

I have AsyncTask that shows progress DialogFragment and dismisses it onPostExecute. Everything works fine, except when onPostExecute happens while application is in background (after pressing Home button, for example). Then I got this error on DialogFragment dismissing - "Can not perform this action after onSaveInstanceState". Doh. Regular dialogs works just fine. But not FragmentDialog.

So I wonder, what is the proper way of dismissing DialogFragment while application is in background? I haven't really worked with Fragments a lot, so I think that I'm just missing something.

Armallas answered 17/2, 2012 at 8:46 Comment(1)
see also here for nice solution using a paused handlerTyphoeus
M
168

DialogFragment has a method called dismissAllowingStateLoss()

Mapping answered 23/4, 2012 at 5:3 Comment(1)
This only works if you use: show(FragmentManager, tag), but not when using show(FragmentTransaction, tag) because popBackStack in dismissInternal calls enqueueAction(..., allowStateLoss=false) even though we asked for allowing state loss. And it does this in both framework and support versions.Cristiecristin
L
10

This is what I did (df == dialogFragment):

Make sure that you call the dialog this way:

df.show(getFragmentManager(), "DialogFragment_FLAG");

When you want to dismis the dialog make this check:

if (df.isResumed()){
  df.dismiss();
}
return;

Make sure that you have the following in the onResume() method of your fragment (not df)

@Override
public void onResume(){
  Fragment f = getFragmentManager().findFragmentByTag("DialogFragment_FLAG");
  if (f != null) {
    DialogFragment df = (DialogFragment) f;
    df.dismiss();
  }
  super.onResume();
}   

This way, the dialog will be dismissed if it's visible.. if not visible the dialog is going to be dismisded next the fragment becomes visible (onResume)...

Letitialetizia answered 21/2, 2013 at 15:20 Comment(2)
This always dismisses the fragment when the user comes back, what if they didn't read the dialog yet, just left the app right after it is shown?Cristiecristin
dismiss() already removes the dialog fragment internally. Source code: getFragmentManager().beginTransaction(); ft.remove(this);Purchasable
A
3

This is what I had to do to achieve what you want: I have a Fragment activity on which i was showing a dialog fragment named fragment_RedemptionPayment which is globally declared at the top. The following code dismisses the DialogFragment if it was showing before the activity goes in background and comes back in foreground.

     @Override
        public void onResume() {
            super.onResume();        
            if(fragment_RedemptionPayment.isVisible()){
                fragment_RedemptionPayment.dismiss();
            }
}
Accident answered 16/4, 2017 at 10:15 Comment(0)
U
2

Another new way of checking the state before calling dismiss is this:

if(!dialog.isStateSaved){
    dialog.dismiss()
} else {
    //Change the UI to suit your functionality
}

In this way its is checked that state is saved or not, basically on pause and onSaveInstanceState has been called.

For Java you can use isStateSaved()

Uvea answered 11/4, 2020 at 9:7 Comment(0)
S
0

A solution that might work is setting Fragment.setRetainInstance(true) in your dialogfragment, but that's not the prettiest of fixes.

Sometimes I have noticed that I have to queue up my dialog actions to let the framework restore the state first. If you can get hold of the current Looper (Activity.getMainLooper()) and wrap that in a Handler you could try passing your dismissal to the back of the queue by posting a runnable on that queue.

I often end up using a separate fragment that it retaininstance(true) that has a ResultReceiver. So i pass on that result receiver to my jobs and handle callbacks in its onReceive (often as a router for other receivers). But that might be a bit more work than it is worth if you are using async tasks.

Slight answered 17/2, 2012 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.