Android TextField: 通过编程方式设置焦点 + 软输入

在我看来,我有一个搜索 EditText 和我想要触发程序行为的点击事件的字段,即给予焦点的文本字段和显示软键盘,如果必要的话(如果没有硬键盘可用)。

我试了 field.requestFocus()。字段实际上得到焦点,但软键盘不显示。

我试过 field.performClick(),但它只调用字段的 OnClickListener。

知道吗?

93887 次浏览

Good sir, try this:

edittext.setFocusableInTouchMode(true);
edittext.requestFocus();

I'm not sure, but this might be required on some phones (some of the older devices):

final InputMethodManager inputMethodManager = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT);

Here is the code that worked for me.

edittext.post(new Runnable() {
public void run() {
edittext.requestFocusFromTouch();
InputMethodManager lManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
lManager.showSoftInput(edittext, 0);
}
});

That's it! Enjoy ;)

The following code worked for me, after the other two answers didn't work for me:

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

Where ShowKeyboard is

private class ShowKeyboard implements Runnable {
@Override
public void run() {
passwordInput.setFocusableInTouchMode(true);
//      passwordInput.requestFocusFromTouch();
passwordInput.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
}
}

After a successful input, I also make sure I hide the keyboard

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

Technically, I just added 300 ms of delay before running the soft keyboard display request. Weird, right? Also changed requestFocus() to requestFocusFromTouch().

EDIT: Don't use requestFocusFromTouch() it gives a touch event to the launcher. Stick with requestFocus().

EDIT2: In Dialogs (DialogFragment), use the following

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

instead of

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        field.post(new Runnable() {
@Override
public void run() {
field.requestFocus();
field.onKeyUp(KeyEvent.KEYCODE_DPAD_CENTER, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
}
});

In my case, I wanted to display the virtual keyboard with no reference to a specific textbox, so I used the first part of the accepted answer to focus :

edittext.setFocusableInTouchMode(true);
edittext.requestFocus();

Then I show the virtual keyboard :

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

In my case just this solved all problems:

val inputMethodManager: InputMethodManager =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT)

I have put it in RecyclerView Adapter, because I use data binding. Also I haven't used edittext.setFocusableInTouchMode(true) because in my layout it is true by default. And don't use this line: edittext.requestFocus(). When I removed it, it started to work :)

for kotlin, implement using extension function as follow

fun View.showSoftKeyboard() {
this.requestFocus()
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

val mAlertDialog = mBuilder.show()

        //Coloca o foo no txtDlgQuantidade e então chama o teclado
mDialogView.txtDlgQuantidade.isFocusable = true
mDialogView.txtDlgQuantidade.isFocusableInTouchMode = true
mDialogView.txtDlgQuantidade.requestFocus()
mAlertDialog.window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
mAlertDialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)