简体   繁体   中英

Simplest yes/no dialog fragment

I'd like to make a dialog fragment that asks "Are you sure?" with a "yes/no" reply.

I've looked at the documentation and it's really verbose, going all over the place, explaining how to make advanced dialog boxes, but no intact code on making a simple 'hello world' kind of dialog box. Most tutorials utilize the deprecated dialog box system. The official blog seems to be unnecessarily complicated and difficult to understand.

So, what's the simplest way to create and display a really basic Alert Dialog? Bonus points if it's using the support library.

A DialogFragment is really just a fragment that wraps a dialog. You can put any kind of dialog in there by creating and returning the dialog in the onCreateDialog() method of the DialogFragment.

Heres an example DialogFragment:

class MyDialogFragment extends DialogFragment{
    Context mContext;
    public MyDialogFragment() {
        mContext = getActivity();
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext);
        alertDialogBuilder.setTitle("Really?");
        alertDialogBuilder.setMessage("Are you sure?");
        //null should be your on click listener
        alertDialogBuilder.setPositiveButton("OK", null);
        alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });


        return alertDialogBuilder.create();
    }
}

To create the dialog call:

new MyDialogFragment().show(getFragmentManager(), "MyDialog");

And to dismiss the dialog from somewhere:

((MyDialogFragment)getFragmentManager().findFragmentByTag("MyDialog")).getDialog().dismiss();

All of that code will work perfectly with the support library, by just changing the imports to use the support library classes.

So, what's the simplest way to create and display a really basic Alert Dialog? Bonus points if it's using the support library.

Simply create a DialogFragment (SDK or support library) and override its onCreateDialog method to return an AlertDialog with the desired text and buttons set on it:

public static class SimpleDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
                .setMessage("Are you sure?")
                .setPositiveButton("Ok", null)
                .setNegativeButton("No way", null)
                .create();
    }

}

To do something when the user uses one of the buttons you'll have to provide an instance of a DialogInterface.OnClickListener instead of the null references from my code.

For those coding with Kotlin and Anko , you can now do dialogs in 4 lines of code:

alert("Order", "Do you want to order this item?") {
    positiveButton("Yes") { processAnOrder() }
    negativeButton("No") { }
}.show()

because of Activity / Fragment lifecycle @athor & @lugsprog approach can fail, more elegant way is to **get activity context from method onAttach and store it as weak reference ** (&try to avoid non default constructor in DialogFragment!, to pass any argument to dialog use arguments) like this:

public class NotReadyDialogFragment extends DialogFragment {

    public static String DIALOG_ARGUMENTS = "not_ready_dialog_fragment_arguments";

    private WeakReference<Context> _contextRef;

    public NotReadyDialogFragment() {
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        /** example pulling of arguments */
        Bundle bundle = getArguments();
        if (bundle!=null) {
            bundle.get(DIALOG_ARGUMENTS);
        }

        //
        // Caution !!!
        // check we can use contex - by call to isAttached 
        // or by checking stored weak reference value itself is not null 
        // or stored in context -> example allowCreateDialog() 
        // - then for example you could throw illegal state exception or return null 
        //
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(_contextRef.get());
        alertDialogBuilder.setMessage("...");
        alertDialogBuilder.setNegativeButton("Przerwij", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        return alertDialogBuilder.create();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        _contextRef = new WeakReference<Context>(activity);
    }

     boolean allowCreateDialog() {
         return _contextRef !== null 
                && _contextRef.get() != null;
     }

EDIT: & if You wanna dismiss dialog then:

  1. try to get it
  2. check if it's exist
  3. check if it's showing
  4. dismiss

something like this :

        NotReadyDialogFragment dialog = ((NotReadyDialogFragment) getActivity().getFragmentManager().findFragmentByTag("MyDialogTag"));
    if (dialog != null) {
        Dialog df = dialog.getDialog();
        if (df != null && df.isShowing()) {
            df.dismiss();
        }
    }

EDIT2: & if u wanna set dialog as non cancelable u should change onCreatweDialog return statement like this:

    /** convert builder to dialog */
    AlertDialog alert = alertDialogBuilder.create();
    /** disable cancel outside touch */
    alert.setCanceledOnTouchOutside(false);
    /** disable cancel on press back button */
    setCancelable(false);

    return alert;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM