Creating your own custom dialogfragment

I came accross an error “java.lang.IllegalStateException: Fragment already added:” whenever I try to show my dialogfragment. FindFragmentByTag is not reliable because I do not like to keep track of the dialog and the surprises that sometime it return NULL.

Here is the example of how one can customize the DialogFragment to your own taste. In this class, I define an extra parameter called isDialogShown to make my life easier so I do not have to rely on getFragmentManager().findFragmentByTag() that most of the time will return null object.

To check if the dialog is up, simple just check mDialogFragment.isDialogShown() and call mDiaglogFragment.dismiss() before fragment.show().

Initialize:

MyCustomDialogFragment dialog = new MyCustomDialogFragment(new OnDialogButtonClickListener(){
    
        @Override
        public void onDialogPositiveClick(int status){
          // Do your stuff here
          dialog.dismiss();
        };

        @Override
        public void onDialogNegativeClick(int status){
          // Do your stuff here
          dialog.dismiss();
        };
});

// Set texts that you want to show in your dialog
dialog.setParameters(....);

Showing dialog:


// Always check if dialog is currently shown
if (dialog.isDialogShown(){
   dialog.dismiss();
}

dialog.show(getFragmentManager(), MyCustomDialogFragment.TAG);

MyCustomDialogFragment class:

public class MyCustomDialogFragment extends DialogFragment{

    public static String TAG = MyCustomDialogFragment.class.getSimpleName();

    // Define listener that will be called when positive/negative button is pressed.
    public interface OnDialogButtonClickListener{
        public void onDialogPositiveClick(int status);
        public void onDialogNegativeClick(int status);
    }

    private OnDialogButtonClickListener mListener;

    private boolean isDialogShown = false;

    private String mTitleLabel="", mBodyLabel="", mPositiveLabel="", mNegativeLabel="";

    public MyCustomDialogFragment(OnDialogButtonClickListener listener){
        mListener = listener;
    }

    /**
     * Method to set dialog parameters
     * @param title for dialog
     * @param content for dialog
     * @param positiveLabel for positive button
     * @param negativeLabel for negative button
     */
    public void setParameters(String title, String content, String positiveLabel, String negativeLabel){
        mTitleLabel = title;
        mBodyLabel = content;
        mPositiveLabel = positiveLabel;
        mNegativeLabel = negativeLabel;
    }

    @Override
    public void show(FragmentManager manager, String tag) {
        super.show(manager, tag);
        isDialogShown = true;
    }

    @Override
    public void dismiss() {
        super.dismiss();
        isDialogShown = false;
    }

    public boolean isDialogShown() {return isDialogShown;}

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(mTitleLabel)
            .setMessage(mBodyLabel)
            .setPositiveButton(mPositiveLabel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    mListener.onDialogPositiveClick(mStatusCode);
                }
            });

        // Sometime, we do not want to show negative button
        if (!mNegativeLabel.equals("")){
            builder.setNegativeButton(mNegativeLabel, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    mListener.onDialogNegativeClick(mStatusCode);
                }
            });
        }

        // Create the AlertDialog object and return it
        return builder.create();
    }
}