From ff498fc206f8be4f484f00baea5396b9b5423dae Mon Sep 17 00:00:00 2001 From: Muhammad Rifqi Priyo Susanto Date: Sat, 1 Jul 2023 14:00:30 +0700 Subject: [PATCH] Android: Reliably showing an IME for text input dialog (#13521) This commit is inspired by this blog post: https://developer.squareup.com/blog/showing-the-android-keyboard-reliably/ --- .../net/minetest/minetest/CustomEditText.java | 39 ++++++++++++++++++- .../net/minetest/minetest/GameActivity.java | 19 +++------ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/android/app/src/main/java/net/minetest/minetest/CustomEditText.java b/android/app/src/main/java/net/minetest/minetest/CustomEditText.java index 8d0a503d0..7a38d0965 100644 --- a/android/app/src/main/java/net/minetest/minetest/CustomEditText.java +++ b/android/app/src/main/java/net/minetest/minetest/CustomEditText.java @@ -2,6 +2,8 @@ Minetest Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik Copyright (C) 2014-2020 ubulem, Bektur Mambetov +Copyright (C) 2023 srifqi, Muhammad Rifqi Priyo Susanto + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -29,17 +31,52 @@ import androidx.appcompat.widget.AppCompatEditText; import java.util.Objects; public class CustomEditText extends AppCompatEditText { + private int editType = 2; // single line text input as default + private boolean wantsToShowKeyboard = false; + public CustomEditText(Context context) { super(context); } + public CustomEditText(Context context, int _editType) { + super(context); + editType = _editType; + } + @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { + // For multi-line, do not close the dialog after pressing back button + if (editType != 1 && keyCode == KeyEvent.KEYCODE_BACK) { InputMethodManager mgr = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); Objects.requireNonNull(mgr).hideSoftInputFromWindow(this.getWindowToken(), 0); } return false; } + + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + tryShowKeyboard(); + } + + public void requestFocusTryShow() { + requestFocus(); + wantsToShowKeyboard = true; + tryShowKeyboard(); + } + + private void tryShowKeyboard() { + if (hasWindowFocus() && wantsToShowKeyboard) { + if (isFocused()) { + CustomEditText that = this; + post(() -> { + final InputMethodManager imm = (InputMethodManager) + getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(that, 0); + }); + } + wantsToShowKeyboard = false; + } + } } diff --git a/android/app/src/main/java/net/minetest/minetest/GameActivity.java b/android/app/src/main/java/net/minetest/minetest/GameActivity.java index d4fb57e44..caac0637d 100644 --- a/android/app/src/main/java/net/minetest/minetest/GameActivity.java +++ b/android/app/src/main/java/net/minetest/minetest/GameActivity.java @@ -31,7 +31,6 @@ import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.Button; -import android.widget.EditText; import android.widget.LinearLayout; import androidx.annotation.Keep; @@ -96,21 +95,11 @@ public class GameActivity extends NativeActivity { container.setOrientation(LinearLayout.VERTICAL); builder.setView(container); AlertDialog alertDialog = builder.create(); - EditText editText; - // For multi-line, do not close the dialog after pressing back button - if (editType == 1) { - editText = new EditText(this); - } else { - editText = new CustomEditText(this); - } + CustomEditText editText = new CustomEditText(this, editType); container.addView(editText); editText.setMaxLines(8); - editText.requestFocus(); editText.setHint(hint); editText.setText(current); - final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); - Objects.requireNonNull(imm).toggleSoftInput(InputMethodManager.SHOW_FORCED, - InputMethodManager.HIDE_IMPLICIT_ONLY); if (editType == 1) editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE); @@ -119,7 +108,8 @@ public class GameActivity extends NativeActivity { InputType.TYPE_TEXT_VARIATION_PASSWORD); else editText.setInputType(InputType.TYPE_CLASS_TEXT); - editText.setSelection(editText.getText().length()); + editText.setSelection(Objects.requireNonNull(editText.getText()).length()); + final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); editText.setOnKeyListener((view, keyCode, event) -> { // For multi-line, do not submit the text after pressing Enter key if (keyCode == KeyEvent.KEYCODE_ENTER && editType != 1) { @@ -143,12 +133,13 @@ public class GameActivity extends NativeActivity { alertDialog.dismiss(); })); } - alertDialog.show(); alertDialog.setOnCancelListener(dialog -> { getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); messageReturnValue = current; messageReturnCode = -1; }); + alertDialog.show(); + editText.requestFocusTryShow(); } public int getDialogState() {