Android Dialog and the correct way to open the soft keyboard

cover

1. Write before

The first blog in 2017, I wish you all a Happy New Year, healthy and safe in the new year!

The main content of this blog is about the display and hiding of the soft keyboard in Dialog. The requirement is to have a password input box in Dialog, pop up the Dialog display soft keyboard, turn off the hidden soft keyboard in Dialog.
Well, is it a bit simple, but there are still some problems in the process of implementation. After trying most of the methods on the Internet, I finally found a good way to share it with you.

Look at the picture:

Dialog

2. Implementation process

Let's start with the initial implementation:

// Show Dialog
dialog.show();

// Show Soft Keyboard
SoftInputUtils.showSoftInput(activity);

But, the soft keyboard is not displayed, there are two ways to display the soft keyboard, the first way is used, the second method has no effect in Dialog.

// First, if the soft keyboard is already displayed on the window, it is hidden and vice versa
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);

// Second, force the soft keyboard to display and view is the current input box object
inputMethodManager.showSoftInput(view,InputMethodManager.SHOW_FORCED);  

So look at the source code of Dialog and see that the display and hiding of Dialog is handled by Handler. Is it possible that the method of displaying the soft keyboard executes too fast, so the soft keyboard is displayed delay after the show method, and it is found that it can be displayed normally.
But deferred processing is obviously not a good way to do this. Is there a way to call back once the Dialog display is complete? Well, yes, there is a setOnShowListener method that displays a soft keyboard in the callback method onShow of the OnShowListener interface.There are no limitations to hiding the soft keyboard, either after dismiss or in the callback method onDismiss.

/**
 * Send a message displaying Dialog
 */
private void sendShowMessage() {
    if (mShowMessage != null) {
        // Obtain a new message so this dialog can be re-used
        Message.obtain(mShowMessage).sendToTarget();
    }
}


/**
 * Receive messages that show or hide Dialog
 */
private static final class ListenersHandler extends Handler {
    private WeakReference<DialogInterface> mDialog;

    public ListenersHandler(Dialog dialog) {
        mDialog = new WeakReference<DialogInterface>(dialog);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case DISMISS:
                ((OnDismissListener) msg.obj).onDismiss(mDialog.get());
                break;
            case CANCEL:
                ((OnCancelListener) msg.obj).onCancel(mDialog.get());
                break;
            case SHOW:
                ((OnShowListener) msg.obj).onShow(mDialog.get());
                break;
        }
    }
}

Delayed display soft keyboard

new Thread() {
    @Override
    public void run() {
        super.run();
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                SoftInputUtils.showSoftInput(activity);
            }
        });
    }
}.start();

3. Code

Show Dialog prompt box

public class DialogUtils {

    private static Dialog dialog;

    /**
     * Dialog Tip box disappear method
     */
    public static void dialogDismiss() {
        if (isDialogShowing()) {
            dialog.dismiss();
            dialog = null;
        }
    }

    /**
     * Dialog Whether the prompt box is running
     *
     * @return Dialog Whether the prompt box is running
     */
    public static boolean isDialogShowing() {
        return dialog != null && dialog.isShowing();
    }


    /**
     * Create Dialog Prompt Box
     *
     * @param context context
     */
    private static void createDialog(Context context) {
        dialogDismiss();
        dialog = new Dialog(context, R.style.SampleTheme);
        dialog.setContentView(R.layout.layout_dialog);
        // Click on the area outside the pop-up window, the pop-up window will not disappear
        dialog.setCanceledOnTouchOutside(false);
    }

    /**
     * Show confirmation security code prompt box
     *
     * @param activity              Current Activity
     * @param dialogOnClickListener Determine Button Click Event
     */
    public static void showSecurityCodeInputDialog(final Activity activity,
                                                   final DialogOnClickListener dialogOnClickListener) {
        createDialog(activity);

        ImageView ivClose = (ImageView) dialog.findViewById(R.id.iv_close);
        final GridPasswordView gpvCode = (GridPasswordView) dialog.findViewById(R.id.gpv_code);
        Button btnOk = (Button) dialog.findViewById(R.id.btn_ok);

        ivClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialogDismiss();
            }
        });
        btnOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String code = gpvCode.getPassWord();
                dialogOnClickListener.onClick(code);
            }
        });

        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                // Get Focus
                gpvCode.requestFocus();
                // Show Soft Keyboard
                SoftInputUtils.showSoftInput(activity);
            }
        });
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                // Hide Soft Keyboard
                SoftInputUtils.hideSoftInput(activity);
            }
        });

        dialog.show();
    }

    public interface DialogOnClickListener {
        /**
         * Click Event
         *
         * @param str Callback Arguments
         */
        public void onClick(String str);
    }
}

Ways to show and hide soft keyboards

public class SoftInputUtils {

    /**
     * Show soft keyboard, Dialog uses
     *
     * @param activity Current Activity
     */
    public static void showSoftInput(Activity activity) {
        InputMethodManager inputMethodManager =
                (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }

    /**
     * Hide Soft Keyboard
     *
     * @param activity Current Activity
     */
    public static void hideSoftInput(Activity activity) {
        InputMethodManager inputMethodManager =
                (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(
                activity.getWindow().getDecorView().getWindowToken(), 0);
    }
}

Call the method that displays the Dialog

DialogUtils.showSecurityCodeInputDialog(this, new DialogUtils.DialogOnClickListener() {
    @Override
    public void onClick(String str) {
        Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
        DialogUtils.dialogDismiss();
    }
});

4. Write at the end

In the frequent tests of showing and turning off Dialog, it was found that sometimes the soft keyboard would not be displayed, but there was no rule found. Students with understanding can leave comments for me.

Welcome to your classmates'comments. If you think this blog is useful for you, leave a message or click on your favorite blog.

Full Demo Download



From: https://www.jianshu.com/p/8cb4fe29bc35

Added by esmarts on Tue, 14 May 2019 19:57:27 +0300