如何在 EditText 获得焦点时显示软键盘

544
我希望在EditText聚焦时(如果设备没有物理键盘),自动显示软键盘,但我有两个问题:
  1. 当我的Activity被显示时,我的EditText已经聚焦了,但是键盘没有显示出来。我需要再次点击它才能显示键盘(应该在Activity显示时就自动显示键盘)。

  2. 当我在键盘上点击完成时,键盘会消失,但是EditText仍然保持聚焦状态,这不是我想要的(因为我的编辑已经完成了)。

总之,我的问题是需要像iPhone一样,保持键盘与我的EditText状态同步(聚焦/未聚焦),并且如果有物理键盘,不要显示软键盘。

我只有一个基本的EditText,如下所示: <EditText android:id="@+id/myEditText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:imeOptions="actionDone" />在我的活动中,我有这个:EditText editTxt = (EditText) findViewById(R.id.myEditText); editTxt.requestFocus(); - Ludovic Landry
2
这比这篇帖子中的任何答案都更有帮助:https://dev59.com/tHE95IYBdhLWcg3wOLQ1#2418314 - Armel Larcier
49个回答

6
editText.post(new Runnable() {
    @Override
    public void run() {
        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
    }
});

5

代码片段……

public void hideKeyboard(Context activityContext){

    InputMethodManager imm = (InputMethodManager)
            activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);

    //android.R.id.content ( https://dev59.com/_Gsz5IYBdhLWcg3wmpL0#12887919 )
    View rootView = ((Activity) activityContext)
            .findViewById(android.R.id.content).getRootView();

    imm.hideSoftInputFromWindow(rootView.getWindowToken(), 0);
}

public void showKeyboard(Context activityContext, final EditText editText){

    final InputMethodManager imm = (InputMethodManager)
            activityContext.getSystemService(Context.INPUT_METHOD_SERVICE);

    if (!editText.hasFocus()) {
        editText.requestFocus();
    }

    editText.post(new Runnable() {
        @Override
        public void run() {
            imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
        }
    });
}

5

在你的清单文件中:

android:windowSoftInputMode="stateAlwaysVisible" - 初始情况下键盘可见。 android:windowSoftInputMode="stateAlwaysHidden" - 初始情况下键盘隐藏。

我喜欢使用 "adjustPan",因为当键盘启动时,屏幕会自动调整。

 <activity
      android:name="YourActivity"
      android:windowSoftInputMode="stateAlwaysHidden|adjustPan"/>

4
final InputMethodManager keyboard = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

toggleSoftInput已被弃用。 - Akito

4
只需在清单文件中添加 android:windowSoftInputMode="stateHidden" 即可。

4

没有一个答案适用于我。这里有一个简单的方法。

searchEditText.setVisibility(View.VISIBLE);
                final Handler handler=new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        searchEditText.requestFocus();
                    }
                }, 400);

将requestFocus()方法的调用推迟400毫秒。


3
在Activity的onResume()部分,您可以调用bringKeyboard()方法。
 onResume() {
     EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
     bringKeyboard(yourEditText);
 }


  protected boolean bringKeyboard(EditText view) {
    if (view == null) {
        return false;
    }
    try {
      // Depending if edittext has some pre-filled values you can decide whether to bring up soft keyboard or not
        String value = view.getText().toString();
        if (value == null) {
            InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
            return true;
        }
    } catch (Exception e) {
        Log.e(TAG, "decideFocus. Exception", e);
    }
    return false;
  }

WidgetUtils.showKeyboard是什么?这是最重要的部分。 - TWiStErRob

3
在您的情况下,您有两个编辑。如果您在活动中只有单个编辑,则上述提供的所有解决方案(附加到您的EditText的OnFocusChangeListener.onFocusChange依赖于InputMethodManager交互)都可以正常工作。
 private EditText tvX, tvY;
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 tvX.setOnFocusChangeListener(this);
    tvY.setOnFocusChangeListener(this);

@Override
public void onFocusChange(View v, boolean hasFocus) {       
    InputMethodManager imm =  (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(tvX.hasFocus() || tvY.hasFocus()) {            
        imm.showSoftInput(v, 0);            
    } else {
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);         
    }       
};

我观察到当tvX获取焦点并显示键盘时,onFocusChange会被触发,但当tvY获取焦点且键盘已隐藏时,同样也会触发onFocusChange。最终,没有键盘可见。
通用解决方案应该在if语句中使用正确的陈述:“如果EditText文本具有焦点,则显示键盘”。

3

我看官方文档说,把View传递到参数中就可以了,例如EditText,但是showSoftKeyboard在横屏时好像不起作用。

private fun showSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
    }
}

private fun closeSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
    }
}

3

对于Kotlin

val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager

fun showKeyboard() {
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
    }

fun hideKeyboard() {
        imm.hideSoftInputFromWindow(phoneNoInputTxt.windowToken, 0);
    }

然后只需调用您想要的内容!


这个答案不完整。无法解决InputMethodManager和IBinder引用。 - Mark Lapasa
@MarkLapasa 请再次检查我的答案,希望能对您有所帮助。谢谢。 - Jamil Hasnine Tamim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接