How to avoid keyboard flickering when opening AlertDialog with EditText while another EditText is already focused?

20 Views Asked by At

I'm trying to open an AlertDialog containing an EditText field. I want the EditText in the AlertDialog to automatically receive focus and show soft keyboard when the dialog opens. I achieve it this way:

dialog.setOnShowListener(d -> {
    dialogInput.requestFocus();
});
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

However, if the soft keyboard is already active when I trigger the dialog, it closes and then reopens quickly, resulting in a jarring animation: Demonstration

How can I prevent this behaviour, and ensure that soft keyboard stays open throughout the AlertDialog opening transition?

Full code to reproduce:

public class MainActivity extends Activity {
    public void noOp(DialogInterface dialog, int which) {}

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout contentView = new FrameLayout(this);
        setContentView(contentView);

        EditText bottomInput = new EditText(this);
        bottomInput.setHint("Bottom input");
        contentView.addView(bottomInput, new LayoutParams(MATCH_PARENT, WRAP_CONTENT, Gravity.BOTTOM));

        Button openDialogButton = new Button(this);
        contentView.addView(openDialogButton, new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.CENTER));
        openDialogButton.setText("Open dialog");
        openDialogButton.setOnClickListener(v -> {
            EditText dialogInput = new EditText(this);
            dialogInput.setHint("Dialog input");
            AlertDialog dialog = new AlertDialog.Builder(this)
                    .setTitle("Title")
                    .setMessage("Message")
                    .setView(dialogInput)
                    .setPositiveButton("Ok", this::noOp)
                    .setNegativeButton("Cancel", this::noOp)
                    .create();
            dialog.setOnShowListener(d -> {
                dialogInput.requestFocus();
            });
            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
            dialog.show();
        });
    }
}
0

There are 0 best solutions below