Android: show soft keyboard automatically when focus is on an EditText
我正在使用
如何在显示对话框时自动显示软键盘? (并且没有物理/硬件键盘)。 与按下"搜索"按钮调用全局搜索的方式类似,将自动显示软键盘。
您可以在
1 2 3 4 5 6 7 8 9 10 | final AlertDialog dialog = ...; editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); } } }); |
用于显示键盘用途:
1 2 | InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); |
隐藏键盘使用:
1 2 | InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(),0); |
您可以在创建对话框后立即请求软键盘(在SDK上测试 - r20)
1 2 3 4 5 | // create dialog final AlertDialog dialog = ...; // request keyboard dialog.getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); |
我有同样的问题,并用以下代码解决了它。我不确定它在具有硬件键盘的手机上的表现如何。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // TextEdit final EditText textEdit = new EditText(this); // Builder AlertDialog.Builder alert = new AlertDialog.Builder(this); alert.setTitle("Enter text"); alert.setView(textEdit); alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String text = textEdit.getText().toString(); finish(); } }); alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); // Dialog AlertDialog dialog = alert.create(); dialog.setOnShowListener(new OnShowListener() { @Override public void onShow(DialogInterface dialog) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(textEdit, InputMethodManager.SHOW_IMPLICIT); } }); dialog.show(); |
我找到了这个例子http://android-codes-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html。在
1 2 | InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); |
1 2 3 4 | <activity ... android:windowSoftInputMode="stateVisible"> </activity> |
要么
1 | getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); |
来自其他答案的代码片段可以工作,但是将它们放在代码中并不总是很明显,特别是如果你使用
1 | alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); |
比较好
1 2 | InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); |
因为如果焦点从EditText切换,SOFT_INPUT_STATE_ALWAYS_VISIBLE将隐藏键盘,其中SHOW_FORCED将保持键盘显示直到它被明确解除,即使用户返回主屏幕或显示最近的应用程序。
下面是使用自定义布局创建的AlertDialog的工作代码,其中EditText是用XML定义的。它还将键盘设置为具有"go"键并允许其触发正按钮。
alert_dialog.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <RelativeLayout android:id="@+id/dialogRelativeLayout" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- android:imeOptions="actionGo" sets the keyboard to have a"go" key instead of a"new line" key. --> <!-- android:inputType="textUri" disables spell check in the EditText and changes the"go" key from a check mark to an arrow. --> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" android:layout_marginBottom="16dp" android:imeOptions="actionGo" android:inputType="textUri"/> </RelativeLayout> |
AlertDialog.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatDialogFragment; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.EditText; public class CreateDialog extends AppCompatDialogFragment { // The public interface is used to send information back to the activity that called CreateDialog. public interface CreateDialogListener { void onCreateDialogCancel(DialogFragment dialog); void onCreateDialogOK(DialogFragment dialog); } CreateDialogListener mListener; // Check to make sure that the activity that called CreateDialog implements both listeners. public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (CreateDialogListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() +" must implement CreateDialogListener."); } } // onCreateDialog requires @NonNull. @Override @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()); LayoutInflater customDialogInflater = getActivity().getLayoutInflater(); // Setup dialogBuilder. alertDialogBuilder.setTitle(R.string.title); alertDialogBuilder.setView(customDialogInflater.inflate(R.layout.alert_dialog, null)); alertDialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mListener.onCreateDialogCancel(CreateDialog.this); } }); alertDialogBuilder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mListener.onCreateDialogOK(CreateDialog.this); } }); // Assign the resulting built dialog to an AlertDialog. final AlertDialog alertDialog = alertDialogBuilder.create(); // Show the keyboard when the dialog is displayed on the screen. alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); // We need to show alertDialog before we can setOnKeyListener below. alertDialog.show(); EditText editText = (EditText) alertDialog.findViewById(R.id.editText); // Allow the"enter" key on the keyboard to execute"OK". editText.setOnKeyListener(new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { // If the event is a key-down event on the"enter" button, select the PositiveButton"OK". if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { // Trigger the create listener. mListener.onCreateDialogOK(CreateDialog.this); // Manually dismiss alertDialog. alertDialog.dismiss(); // Consume the event. return true; } else { // If any other key was pressed, do not consume the event. return false; } } }); // onCreateDialog requires the return of an AlertDialog. return alertDialog; } } |
嗯,这是一个相当古老的帖子,还有一些东西需要补充。这些是两种简单的方法,可以帮助我控制键盘,它们的工作非常完美:
显示键盘
1 2 3 4 5 6 | public void showKeyboard() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); View v = getCurrentFocus(); if (v != null) imm.showSoftInput(v, 0); } |
隐藏键盘
1 2 3 4 5 6 | public void hideKeyboard() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); View v = getCurrentFocus(); if (v != null) imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } |
让我指出一些额外的信息到yuku的解决方案,因为我发现很难让这个工作!如何从AlertDialog.Builder获取AlertDialog对象?嗯,这是我执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()); final EditText input = new EditText(getActivity()); alert.setView(input); // do what you need, like setting positive and negative buttons... final AlertDialog dialog = alert.show(); input.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus) { dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); } } }); |
看一下处理手动隐藏和显示IME的讨论。但是,我的感觉是,如果焦点
是的,你可以用
1 2 3 4 5 6 7 8 | editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); } } }); |
如果有人得到:
Cannot make a static reference to the non-static method getSystemService(String) from the type Activity
BLOCKQUOTE>
尝试向getSystemService调用添加上下文。
所以
1
2
3 InputMethodManager imm =
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
问题似乎是因为您最初隐藏输入文本的位置(或嵌套或其他东西),AlertDialog会自动设置标志
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 或WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE ,这样就不会触发显示的软输入。解决此问题的方法是添加以下内容:
1
2
3
4
5
6
7
8 (...)
// Create the dialog and show it
Dialog dialog = builder.create()
dialog.show();
// After show (this is important specially if you have a list, a pager or other view that uses a adapter), clear the flags and set the soft input mode
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
最初的问题涉及Dialogs和我的EditText是常规视图。无论如何,我怀疑这对大多数人来说也应该有效。所以这对我有用(上面提出的评价最高的方法对我没有任何帮助)。这是一个自定义的EditView来执行此操作(子类化不是必需的,但我发现它很方便我的目的,因为我想在视图变得可见时抓住焦点)。
这实际上与tidbecks答案大致相同。实际上我没有注意到他的回答,因为它的票数为零。然后我就要评论他的帖子了,但这太长了,所以无论如何我都结束了这个帖子。 tidbeck指出,他不确定如何使用键盘设备。我可以确认在任何一种情况下行为似乎完全相同。这样,在纵向模式下,软件键盘会弹出,而在横向上则不会。物理键盘滑出或没有在我的手机上没有任何区别。
因为,我个人发现我选择使用的行为有点尴尬:
InputMethodManager.SHOW_FORCED 。这是我希望它工作的工作原理。无论方向如何,键盘都可见,但是,如果硬件键盘滑出,至少在我的设备上它不会弹出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 import android.app.Service;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
public class BringOutTheSoftInputOnFocusEditTextView extends EditText {
protected InputMethodManager inputMethodManager;
public BringOutTheSoftInputOnFocusEditTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public BringOutTheSoftInputOnFocusEditTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BringOutTheSoftInputOnFocusEditTextView(Context context) {
super(context);
init();
}
private void init() {
this.inputMethodManager = (InputMethodManager)getContext().getSystemService(Service.INPUT_METHOD_SERVICE);
this.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
BringOutTheSoftInputOnFocusEditTextView.this.inputMethodManager.showSoftInput(BringOutTheSoftInputOnFocusEditTextView.this, InputMethodManager.SHOW_FORCED);
}
}
});
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (visibility == View.VISIBLE) {
BringOutTheSoftInputOnFocusEditTextView.this.requestFocus();
}
}
}
将这些方法放在Util类中并随处使用。
科特林
1
2
3
4
5
6
7
8
9
10
11
12
13 fun hideKeyboard(activity: Activity) {
val view = activity.currentFocus
val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
private fun showKeyboard(activity: Activity) {
val view = activity.currentFocus
val methodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}Java的
1
2
3
4
5
6
7
8
9
10
11
12
13 public static void hideKeyboard(Activity activity) {
View view = activity.getCurrentFocus();
InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert methodManager != null && view != null;
methodManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
private static void showKeyboard(Activity activity) {
View view = activity.getCurrentFocus();
InputMethodManager methodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
assert methodManager != null && view != null;
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
尝试并使用:
1
2
3 editText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
我创建了很好的kotlin-esqe扩展功能,任何人都有兴趣
1
2
3
4
5
6
7
8
9
10
11
12
13 fun Activity.hideKeyBoard() {
val view = this.currentFocus
val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.hideSoftInputFromWindow(view!!.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
fun Activity.showKeyboard() {
val view = this.currentFocus
val methodManager = this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
assert(view != null)
methodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}
为了显示键盘,对我来说,我必须做以下事情
Android TextField:以编程方式设置焦点+软输入
基本上解决方案如下
1
2
3
4
5
6 @Override
public void onResume() {
super.onResume();
//passwordInput.requestFocus(); <-- that doesn't work
passwordInput.postDelayed(new ShowKeyboard(), 325); //250 sometimes doesn't run if returning from LockScreen
}其中
ShowKeyboard 是
1
2
3
4
5
6
7
8
9
10 private class ShowKeyboard implements Runnable {
@Override
public void run() {
passwordInput.setFocusableInTouchMode(true);
//passwordInput.requestFocusFromTouch(); //this gives touch event to launcher in background -_-
passwordInput.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
}
}输入成功后,我也确保隐藏键盘
1
2
3 getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(getView().getWindowToken(), 0);
为什么这个答案 - 因为上面的解决方案会显示你的键盘,但如果你点击
EditText 以外的任何地方它就不会消失。因此,当EditText 失去焦点时,你需要做一些事情来使keybaord消失。您可以通过执行以下步骤来实现此目的:
通过添加以下属性,使父视图(活动的内容视图)可单击并可聚焦
1
2 android:clickable="true"
android:focusableInTouchMode="true"实现hideKeyboard()方法
1
2
3
4 public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_IMPLICIT_ONLY );
}最后,设置edittext的onFocusChangeListener。
1
2
3
4
5
6
7
8 edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
hideKeyboard(v);
}
}
});
我知道这个问题很老了我认为使用扩展功能是一种更好的方式来显示编辑文本的键盘
这是我用来显示edittext键盘的方法。
kotlin代码:
只需要调用edittext.showKeyboard()
1
2
3
4
5
6
7 fun EditText.showKeyboard() {
post {
requestFocus()
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}
}java代码:
1
2
3
4
5
6
7
8
9
10
11 public static void showKeyboard(EditText editText) {
editText.post(new Runnable() {
@Override
public void run() {
editText.requestFocus();
InputMethodManager imm = (InputMethodManager) editText.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
});
}
这有点棘手。我这样做了,它起作用了。
1.首先调用以隐藏窗口中的软输入。如果软键盘可见,这将隐藏软输入,如果不可见则不执行任何操作。
2.显示你的对话
3.然后简单地调用切换软输入。
码:
1
2
3
4
5
6
7 InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
//hiding soft input
inputManager.hideSoftInputFromWindow(findViewById(android.R.id.content).getWind??owToken(), 0);
//show dialog
yourDialog.show();
//toggle soft input
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.SHOW_IMPLICIT);
试试这个
SomeUtils.java
1
2
3
4
5
6
7
8 public static void showKeyboard(Activity activity, boolean show) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if(show)
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
else
inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,0);
}
看看https://stackoverflow.com/a/39144104/2914140我简化了一下:
1
2
3
4
5
6
7
8
9
10
11 // In onCreateView():
view.edit_text.run {
requestFocus()
post { showKeyboard(this) }
}
fun showKeyboard(view: View) {
val imm = view.context.getSystemService(
Context.INPUT_METHOD_SERVICE) as InputMethodManager?
imm?.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
}它比https://stackoverflow.com/a/11155404/2914140更好:
1
2 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);因为当您按Home键并移动到主屏幕时,键盘将保持打开状态。
试过很多,但这对我有用(kotlin):
1
2
3
4
5
6
7
8
9
10
11
12
13 val dialog = builder.create()
dialog.setOnShowListener {
nameEditText.requestFocus()
val s = ContextCompat.getSystemService(requireContext(), InputMethodManager::class.java)
s?.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
}
dialog.setOnDismissListener {
val s = ContextCompat.getSystemService(requireContext(), InputMethodManager::class.java)
s?.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)
}
dialog.show()
这是一个很好的样本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:id="@+id/scrollID"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1">
<LinearLayout
android:id="@+id/test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:weightSum="1">
<EditText
android:id="@+id/txtInpuConversation"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:hint="@string/edt_Conversation">
<requestFocus />
</EditText>
<Button
android:id="@+id/btnSend"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="@string/btn_Conversation" />
</LinearLayout>
</LinearLayout>
1 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);当我进入Activity时,我在onCreate()中调用它来自动显示键盘。