[JAVA] Practice to unify Dialog implementation

Overview

When implementing Dialog on Android, I often used the method of implementing DialogFragment as an inner class in Activity, but I felt that the number of steps of Activity would be large and it would be difficult to know where Dialog is. , I thought of a practice to unify the implementation of Dialog.

Details

Use Factory for displaying Dialog instead of implementing Dialog in Activity. Dialog show is also left to the common class instead of Activity. Please get the source code from GitHub. https://github.com/ken-maki/k_commons.dialog

The configuration is as follows.

com.android.k.commons.dialog ┣lib ┃┣BaseDialogFactory ┃┃ Dialog BaseFactory class, common implementation for Dialog generation is written here. ┃┣AlertDialogFactory ┃┃ Parent Factory class for AlertDialog implementation, inherit this class when creating a new AlertDialog. ┃┣DialogGenerator ┃ ┃ Pass the class that handles Dialog display, Factory, and let it Dialog. ┃┃ The implementation of control at the time of Dialog generation (for example, suppressing duplicate display) is written here. ┃┗CommonAlertDialog ┃ AlertDialog body. Get Builder from Factory taken as an argument and use it as Builder of onCreateDialog. ┣mydialog ┃┣MySampleFooDialogFactory ┃┃DialogFactory for sample, pattern to implement button click event in Factory. ┃┗MySampleBarDialogFactory ┃DialogFactory for sample, pattern to implement button click event with listener set in Factory. ┗MainActivity Dialog display sample Activity. Implement OnClickListener by yourself when MySampleBarDialogFactory is displayed.

Source description

Library part

AlertDialogFactory.java


abstract class BaseDialogFactory implements Serializable {

    DialogInterface.OnCancelListener mOnCancelListener;
    DialogInterface.OnDismissListener mOnDismissListener;

    /**
     * Activity to display Dialog.
     */
    private Activity mActivity;

    /**
     * Constructor.
     *
     * @param activity create dialog for activity.
     */
    BaseDialogFactory(Activity activity) {
        if (activity == null) throw new IllegalArgumentException("activity is null.");
        mActivity = activity;
    }

    /**
     * get Activity.
     *
     * @return Activity
     */
    protected Activity getActivity() {
        return mActivity;
    }

    /**
     * get Dialog Tag.
     *
     * @return Dialog Tag
     */
    protected String getTag() {
        return this.getClass().getSimpleName();
    }

    /**
     * set OnCancelListener.
     * @param listener action listener
     */
    public void setOnCancelListener(DialogInterface.OnCancelListener listener) {
        mOnCancelListener = listener;
    }

    /**
     * set OnDismissListener.
     * @param listener action listener
     */
    public void setOnDismissListener(DialogInterface.OnDismissListener listener) {
        mOnDismissListener = listener;
    }
}

The parent class of DialogFactory and common processing are implemented.

AlertDialogFactory.java


public abstract class AlertDialogFactory extends BaseDialogFactory {

    protected DialogInterface.OnClickListener mPositiveClickListener;
    protected DialogInterface.OnClickListener mNegativeClickListener;

    /**
     * Constructor.
     *
     * @param activity create dialog for activity.
     */
    public AlertDialogFactory(Activity activity) {
        super(activity);
    }

    /**
     * create AlertDialog.Builder.
     *
     * @return can be Show AlertDialog.Builder
     */
    public abstract AlertDialog.Builder build();

    /**
     * set OnClickListener for PositiveButton click.
     * @param listener action listener
     */
    public void setPositiveOnClickListener(DialogInterface.OnClickListener listener) {
        mPositiveClickListener = listener;
    }

    /**
     * set OnClickListener for NegativeButton click.
     * @param listener action listener
     */
    public void setNegativeClickListener(DialogInterface.OnClickListener listener) {
        mNegativeClickListener = listener;
    }
}

AlertDialog Factory class. The parent build () method is the protagonist of this class. The class that inherits AlertDialogFactory is the information you want to display in the build () method. All you have to do is create an implementation that creates and returns AlertDialog.Builder. If you want to use a Dialog other than AlertDialog, it's like AlertDialogFactory Create a parent Factory. (SingleChoiceDialogFactory or DatePickerDialogFactory)

CommonAlertDialog.java


public class CommonAlertDialog extends DialogFragment {
    private static final String ARG_KEY_FACTORY = "f";

    AlertDialogFactory mFactory;

    public static CommonAlertDialog newInstance(AlertDialogFactory factory) {
        Bundle bundle = new Bundle();
        bundle.putSerializable(ARG_KEY_FACTORY, factory);

        CommonAlertDialog dialog = new CommonAlertDialog();
        dialog.setArguments(bundle);
        return dialog;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        mFactory = (AlertDialogFactory)
                getArguments().getSerializable(ARG_KEY_FACTORY);
        if (mFactory == null) throw new IllegalArgumentException("factory is null.");

        AlertDialog.Builder builder = mFactory.build();
        if (builder == null) throw new IllegalStateException("AlertDialog.Builder is null.");
        return builder.create();
    }

    @Override
    public void onCancel(DialogInterface dialog) {
        super.onCancel(dialog);
        if (mFactory.mOnCancelListener != null) {
            mFactory.mOnCancelListener.onCancel(dialog);
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if (mFactory.mOnDismissListener != null) {
            mFactory.mOnDismissListener.onDismiss(dialog);
        }
    }

    /**
     * return AlertDialogFactory.
     * @return AlertDialogFactory
     */
    public AlertDialogFactory getFactory() {
        return mFactory;
    }
}

Dialog body. There are roughly two things I'm doing. -Get Factory from the argument and create it. -Execute when the DialogInterface event is set.

Individual implementation parts

MySampleFooDialogFactory.java


public class MySampleFooDialogFactory extends AlertDialogFactory {

    public MySampleFooDialogFactory(Activity activity) {
        super(activity);
    }

    @Override
    public AlertDialog.Builder build() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        builder.setTitle("Foo Dialog");
        builder.setMessage("This Foo Dialog. please Button Click.");
        builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getActivity(), "Ok clicked.(listener setting from factory)", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getActivity(), "Cancel clicked.(listener setting from factory)", Toast.LENGTH_SHORT).show();
                dialog.dismiss();
            }
        });

        builder.setCancelable(false);
        return builder;
    }
}

Just inherit AlertDialogFactory and implement build (). The sample is a simple implementation, but also for complex Dialogs that use custom layouts etc. The process is implemented in build (). By doing this, when creating a Dialog, you can concentrate only on creating the contents of the Dialog.

merit

-Dialog implementers can focus solely on implementing the code that generates AlertDialog.Builder. Common processing is Dialog Generator, AlertDialogFactory, CommonAlertDialog By implementing it, the entire AlertDialog will behave in a unified manner. -There is no implementation of Dialog and show of Dialog directly in Activity Since it is loosely coupled with Activity, it should be easier to change on the Dialog side compared to the implementation in the inner class.

At the end

It was Qiita's first post, but I wonder if an article like this is okay. I will continue to post articles through trial and error, so I hope you will keep an eye on me.

Source code https://github.com/ken-maki/k_commons.dialog

Recommended Posts

Practice to unify Dialog implementation
Introduction to swift practice output Chapter5
Android Development-Try to display a dialog-
[Android] How to make Dialog Fragment