Skip to content

Commit ff498fc

Browse files
authored
Android: Reliably showing an IME for text input dialog (luanti-org#13521)
This commit is inspired by this blog post: https://developer.squareup.com/blog/showing-the-android-keyboard-reliably/
1 parent 0ade097 commit ff498fc

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

android/app/src/main/java/net/minetest/minetest/CustomEditText.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Minetest
33
Copyright (C) 2014-2020 MoNTE48, Maksim Gamarnik <[email protected]>
44
Copyright (C) 2014-2020 ubulem, Bektur Mambetov <[email protected]>
5+
Copyright (C) 2023 srifqi, Muhammad Rifqi Priyo Susanto
6+
57
68
This program is free software; you can redistribute it and/or modify
79
it under the terms of the GNU Lesser General Public License as published by
@@ -29,17 +31,52 @@
2931
import java.util.Objects;
3032

3133
public class CustomEditText extends AppCompatEditText {
34+
private int editType = 2; // single line text input as default
35+
private boolean wantsToShowKeyboard = false;
36+
3237
public CustomEditText(Context context) {
3338
super(context);
3439
}
3540

41+
public CustomEditText(Context context, int _editType) {
42+
super(context);
43+
editType = _editType;
44+
}
45+
3646
@Override
3747
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
38-
if (keyCode == KeyEvent.KEYCODE_BACK) {
48+
// For multi-line, do not close the dialog after pressing back button
49+
if (editType != 1 && keyCode == KeyEvent.KEYCODE_BACK) {
3950
InputMethodManager mgr = (InputMethodManager)
4051
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
4152
Objects.requireNonNull(mgr).hideSoftInputFromWindow(this.getWindowToken(), 0);
4253
}
4354
return false;
4455
}
56+
57+
@Override
58+
public void onWindowFocusChanged(boolean hasWindowFocus) {
59+
super.onWindowFocusChanged(hasWindowFocus);
60+
tryShowKeyboard();
61+
}
62+
63+
public void requestFocusTryShow() {
64+
requestFocus();
65+
wantsToShowKeyboard = true;
66+
tryShowKeyboard();
67+
}
68+
69+
private void tryShowKeyboard() {
70+
if (hasWindowFocus() && wantsToShowKeyboard) {
71+
if (isFocused()) {
72+
CustomEditText that = this;
73+
post(() -> {
74+
final InputMethodManager imm = (InputMethodManager)
75+
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
76+
imm.showSoftInput(that, 0);
77+
});
78+
}
79+
wantsToShowKeyboard = false;
80+
}
81+
}
4582
}

android/app/src/main/java/net/minetest/minetest/GameActivity.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import android.view.WindowManager;
3232
import android.view.inputmethod.InputMethodManager;
3333
import android.widget.Button;
34-
import android.widget.EditText;
3534
import android.widget.LinearLayout;
3635

3736
import androidx.annotation.Keep;
@@ -96,21 +95,11 @@ private void showDialogUI(String hint, String current, int editType) {
9695
container.setOrientation(LinearLayout.VERTICAL);
9796
builder.setView(container);
9897
AlertDialog alertDialog = builder.create();
99-
EditText editText;
100-
// For multi-line, do not close the dialog after pressing back button
101-
if (editType == 1) {
102-
editText = new EditText(this);
103-
} else {
104-
editText = new CustomEditText(this);
105-
}
98+
CustomEditText editText = new CustomEditText(this, editType);
10699
container.addView(editText);
107100
editText.setMaxLines(8);
108-
editText.requestFocus();
109101
editText.setHint(hint);
110102
editText.setText(current);
111-
final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
112-
Objects.requireNonNull(imm).toggleSoftInput(InputMethodManager.SHOW_FORCED,
113-
InputMethodManager.HIDE_IMPLICIT_ONLY);
114103
if (editType == 1)
115104
editText.setInputType(InputType.TYPE_CLASS_TEXT |
116105
InputType.TYPE_TEXT_FLAG_MULTI_LINE);
@@ -119,7 +108,8 @@ else if (editType == 3)
119108
InputType.TYPE_TEXT_VARIATION_PASSWORD);
120109
else
121110
editText.setInputType(InputType.TYPE_CLASS_TEXT);
122-
editText.setSelection(editText.getText().length());
111+
editText.setSelection(Objects.requireNonNull(editText.getText()).length());
112+
final InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
123113
editText.setOnKeyListener((view, keyCode, event) -> {
124114
// For multi-line, do not submit the text after pressing Enter key
125115
if (keyCode == KeyEvent.KEYCODE_ENTER && editType != 1) {
@@ -143,12 +133,13 @@ else if (editType == 3)
143133
alertDialog.dismiss();
144134
}));
145135
}
146-
alertDialog.show();
147136
alertDialog.setOnCancelListener(dialog -> {
148137
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
149138
messageReturnValue = current;
150139
messageReturnCode = -1;
151140
});
141+
alertDialog.show();
142+
editText.requestFocusTryShow();
152143
}
153144

154145
public int getDialogState() {

0 commit comments

Comments
 (0)