52

I have a Fragment that can create and pop up a DialogFragment, but when I hit the back button, it dismisses the dialog even though I explicitly call setCancelable(false); Is there any way for my DialogFragment to be insensative to the back button?

public class LoadingDialogFragment extends DialogFragment
{
    String title;
    String msg;

    public LoadingDialogFragment()
    {
        this.title = "Loading...";
        this.msg = "Please wait...";
    }
    public LoadingDialogFragment(String title, String msg)
    {
        this.title = title;
        this.msg = msg;
    }

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState)
    {
        final ProgressDialog dialog = new ProgressDialog(getActivity());

        dialog.setTitle(title);
        dialog.setMessage(msg);
        dialog.setIndeterminate(true);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setCancelable(false);

        return dialog;
    }

}

I create the DialogFragment from an AsyncTask:

private class GpsTask extends AsyncTask<String, Integer, Integer>
{
    //ProgressDialog dialog;
    @Override
    protected void onPreExecute()
    {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        DialogFragment newFragment = new LoadingDialogFragment("Gathering Location", "Acquiring GPS lock...");
        ft.addToBackStack(null);
        newFragment.show(ft, "dialog");
    }

    @Override
    protected Integer doInBackground(String... params)
    {
        //acquire a GPS lock and grab a few position updates
    }

    @Override
    protected void onProgressUpdate(Integer... input) { }

    @Override
    protected void onPostExecute(Integer result)
    {
        getSupportFragmentManager().popBackStackImmediate();
    }
}
Adil Hussain
  • 24,783
  • 20
  • 95
  • 134
MattF
  • 1,425
  • 3
  • 16
  • 18

3 Answers3

131

How about using setCancelable? Did you try it?

From the Docs -

Control whether the shown Dialog is cancelable. Use this instead of directly calling Dialog.setCancelable(boolean), because DialogFragment needs to change its behavior based on this

Lalit Poptani
  • 65,659
  • 21
  • 155
  • 238
  • 42
    This is correct! it turns out you have to call setCancelable(false) on the DialogFragment itself, not the inner Dialog that it holds! – MattF Apr 16 '12 at 10:02
  • 2
    @MattF This comment is a life saver. Did not realize i needed to call `setCancelable()` on the `DialogFragment` instead of the `ProgressDialog`. Thanks! – prolink007 Sep 22 '15 at 15:40
  • 2
    I used `isCancelable = false` in Kotlin, inside of `onViewCreated` and it worked!! – Seven Feb 26 '19 at 22:09
  • It works for me too @Seven, i use isCancelable = false (not dialog.setCancelable(false)) – Fernando Perez Jul 19 '19 at 00:10
  • I was using ```getDialog.setCancelable(false)``` and it didn't work, but I replaced it with ```setCancelable(false)``` and it works correctly. that's was weird – Ehsan Dec 14 '19 at 12:43
4

I'm not at all sure if this'll work with FragmentDialogs, but if the setCancelable didn't work for you, it might be worth having a look at this article: Android: Prompt user to save changes when Back button is pressed

It explains how to detect the back button being pressed. So maybe you can suppress the button press and it'll stop the dialog from closing?

Community
  • 1
  • 1
manavo
  • 1,770
  • 2
  • 13
  • 16
3

It may help you.

newFragment.setCancelable(false); 

make changes like above when creating DialogFragment object or in the constructor of Custom DialogFragment as in the sample below.

public static CustomClearHourDialog newInstance(Bundle args, IDialogListener listener)
        {
            CustomClearHourDialog clearHourDialog = new CustomClearHourDialog();            
            CustomClearHourDialog.listener = listener;
            clearHourDialog.setCancelable(false);
            return clearHourDialog;
        }
Karthikeyan Ve
  • 2,151
  • 2
  • 19
  • 36