Android:在焦点位于EditText时自动显示软键盘

我正在使用AlertDialog显示一个input框。 当我调用AlertDialog.show() ,对话框中的EditText自动聚焦,但软键盘不会自动显示。

如何在显示对话框时自动显示软键盘? (并且没有物理/硬件键盘)。 类似于当我按searchbutton来调用全局search时,软键盘会自动显示。

您可以在AlertDialog上的EditText上创build一个焦点侦听AlertDialog ,然后获取AlertDialogWindow 。 从那里你可以通过调用setSoftInputMode软键盘显示。

 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); } } }); 

为显示键盘使用:

 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); 

隐藏键盘使用:

 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(),0); 

您可以在创build对话框后立即请求软键盘(在SDK-r20上进行testing)

 // create dialog final AlertDialog dialog = ...; // request keyboard dialog.getWindow().setSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 

我有同样的问题,并用下面的代码解决它。 我不确定它是如何在具有硬件键盘的电话上performance的。

 // 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-code-examples.blogspot.com/2011/11/show-or-hide-soft-keyboard-on-opening.html 。 在alert.show()之前添加下面的代码。

 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); 
 <activity ... android:windowSoftInputMode="stateVisible" > </activity> 

要么

 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 

从其他答案的代码片段工作,但它并不总是显而易见的地方放在代码中,特别是如果您使用AlertDialog.Builder并按照官方对话框教程,因为它不使用final AlertDialog ...alertDialog.show()

 alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 

比…更可取

 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); 

由于SOFT_INPUT_STATE_ALWAYS_VISIBLE会在焦点离开EditText时隐藏键盘,其中SHOW_FORCED将保持键盘显示直到被明确解除,即使用户返回到主屏幕或显示最近的应用程序。

下面是一个AlertDialog的工作代码,这个AlertDialog使用一个自定义的布局,并且在XML中定义了一个EditText。 它也设置键盘有一个“去”键,并允许它触发正面的button。

alert_dialog.xml:

 <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:

 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; } } 

让我来指出一些额外的信息到yuku的解决scheme,因为我发现很难得到这个工作! 如何从AlertDialog.Builder中获取AlertDialog对象? 那么,这是我的alert.show()执行的结果:

 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); } } }); 

看看这个处理手动隐藏和显示input法的讨论。 然而,我的感觉是,如果一个聚焦的EditText没有把IME带上来,那是因为你正在调用你的OnCreate() AlertDialog.show() OnCreate()或者在屏幕实际出现之前引发的其他方法。 把它移动到OnPostResume()应该解决它的情况下,我相信。

那么这是一个很老的post,还有一些东西要补充。
这两个简单的方法可以帮助我控制键盘,而且他们的工作非常完美:

显示键盘

 public void showKeyboard() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); View v = getCurrentFocus(); if (v != null) imm.showSoftInput(v, 0); } 

隐藏键盘

 public void hideKeyboard() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); View v = getCurrentFocus(); if (v != null) imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } 

是的,你可以用setOnFocusChangeListener来做,它会帮助你。

 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); } } }); 

如果有人得到:

无法对types为Activity的非静态方法getSystemService(String)进行静态引用

尝试添加上下文到getSystemService调用。

所以

 InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0); 

原来的问题涉及到对话框和我的EditText是定期的看法。 无论如何,我怀疑这应该适用于你们大多数人。 所以这里有什么适合我(上面build议的最高评分方法对我没有任何帮助)。 这是一个自定义的EditView,这样做(子类化是没有必要的,但我发现它方便我的目的,因为我也想抓住焦点,当视图变得可见)。

这实际上与tidbecks的答案基本相同。 我其实没有注意到他的答案,因为它没有票数。 然后,我刚刚评论他的post,但是会太长,所以我结束了这个post。 tidbeck指出,他不确定它如何与键盘设备的工作。 我可以证实这两种情况下的行为似乎完全一样。 在纵向模式下,软件键盘会popup,而在横向上则不会。 物理键盘滑出或不在我的手机上没有任何区别。

因为,我个人发现我select使用的行为有些尴尬: InputMethodManager.SHOW_FORCED 。 这工作,因为我想它的工作。 不pipe方向如何,键盘都可以看到,但至less在我的设备上,如果硬件键盘滑出,它不会popup。

 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(); } } } 

这个问题似乎是因为你input文本的地方最初是隐藏的(或嵌套的或者其他的东西),AlertDialog自动设置标志WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM或者WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE这样事情就不会触发软input现身。

解决这个问题的方法是添加以下内容:

 (...) // 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); 

尝试和使用:

 editText.requestFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); 

为了显示键盘,对我来说,我必须做到以下几点

Android TextField:以编程方式设置焦点+软input

本质上,解决scheme如下

 @Override public void onResume() { super.onResume(); //passwordInput.requestFocus(); <-- that doesn't work passwordInput.postDelayed(new ShowKeyboard(), 300); //250 sometimes doesn't run if returning from LockScreen } 

ShowKeyboard地方在哪里

 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); } } 

input成功后,我也确定我隐藏了键盘

 getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); ((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)) .hideSoftInputFromWindow(getView().getWindowToken(), 0); 

这对你来说是很好的例子:

 <?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> 

为什么这个答案 – 因为上面的解决scheme会显示你的键盘,但是如果你点击EditText其他地方,它也不会消失。 所以当EditText失去焦点时,你需要做一些事情来使keyba消失。

您可以通过执行以下步骤来实现此目的:

  1. 通过添加以下属性使父视图(您的活动的内容视图)可点击和可聚焦

      android:clickable="true" android:focusableInTouchMode="true" 
  2. 实现一个hideKeyboard()方法

      public void hideKeyboard(View view) { InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),InputMethodManager.HIDE_IMPLICIT_ONLY ); } 
  3. 最后,设置你的edittext的onFocusChangeListener。

      edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { hideKeyboard(v); } } }); 

这有点棘手。 我这样做,它的工作。

1.首先调用从窗口隐藏软input。 这将隐藏软input,如果软键盘是可见的,或者什么都不做。

2.显示你的对话框

3.然后简单地调用来切换软input。

码:

 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);