Preventing the back button from cancelling a DialogFragment

AndroidAndroid AsynctaskProgressdialogFragmentBack Button

Android Problem Overview


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();
	}
}

Android Solutions


Solution 1 - Android

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

For custom DialogFragment

Add isCancelable = false at onCreateDialog

Solution 2 - Android

 DialogFragment newFragment = YourFragment.newInstance();
                newFragment.setCancelable(false);
                newFragment.show(fragmentTransaction, "dialog");

Add setCancelable(false) before you .Show() the fragment

Solution 3 - Android

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: https://stackoverflow.com/questions/2459848/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?

Solution 4 - Android

onCreateDialog vs onCreateView:

> Implementations should override this class and implement > onCreateView(LayoutInflater, ViewGroup, Bundle) to supply the content > of the dialog. Alternatively, they can override onCreateDialog(Bundle) > to create an entirely custom dialog, such as an AlertDialog, with its > own content.

Important when using onCreateDialog:

> Override to build your own custom Dialog container. This is typically > used to show an AlertDialog instead of a generic Dialog; when doing > so, onCreateView(LayoutInflater, ViewGroup, Bundle) does not need to > be implemented since the AlertDialog takes care of its own content.

Example Dialog (In this case an AlertDialog):

public static class MyAlertDialogFragment extends DialogFragment {

    public static MyAlertDialogFragment newInstance(int title) {
        MyAlertDialogFragment frag = new MyAlertDialogFragment();
        Bundle args = new Bundle();
        args.putInt("title", title);
        frag.setArguments(args);
        return frag;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int title = getArguments().getInt("title");

        return new AlertDialog.Builder(getActivity())
                .setIcon(R.drawable.alert_dialog_icon)
                .setTitle(title)
                .setCanceble(false)
                .setPositiveButton(R.string.alert_dialog_ok,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            ((FragmentAlertDialog)getActivity()).doPositiveClick();
                        }
                    }
                )
                .setNegativeButton(R.string.alert_dialog_cancel,
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int whichButton) {
                            ((FragmentAlertDialog)getActivity()).doNegativeClick();
                        }
                    }
                )
                .create();
    }
} 

The property setCanceble(boolean) states whether you can exit the Dialog with a back press. No need to catch the KEYCODE_BACK anywhere.

Solution 5 - Android

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;
        }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattFView Question on Stackoverflow
Solution 1 - AndroidLalit PoptaniView Answer on Stackoverflow
Solution 2 - AndroidDeejaygeekoutView Answer on Stackoverflow
Solution 3 - AndroidmanavoView Answer on Stackoverflow
Solution 4 - AndroidDroidBenderView Answer on Stackoverflow
Solution 5 - AndroidKarthikeyan VeView Answer on Stackoverflow