Preventing the back button from cancelling a DialogFragment
AndroidAndroid AsynctaskProgressdialogFragmentBack ButtonAndroid 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;
}