如何在 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个回答

11

Kotlin键盘显示扩展。

这是之前回答的组合,其中要么太长,要么不完整。

此扩展将在请求焦点后,在消息队列上发布一个可运行项,显示软键盘:

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

需要时从任何视图中调用:

editText.showSoftKeyboard()

10
有时候,raukodraug的答案不起作用。我通过一些尝试和错误的方式来解决这个问题:

有时候,raukodraug的答案不起作用。我通过一些尝试和错误的方式来解决这个问题:

public static void showKeyboard(Activity activity) {
    if (activity != null) {
        activity.getWindow()
                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }
}

public static void hideKeyboard(Activity activity) {
    if (activity != null) {
        activity.getWindow()
                .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    }
}

并且 EditText 部分:

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

1
这是在Android 5上对我有效的唯一解决方案。 - user1021430

10

隐藏键盘,请使用此方法:

getActivity().getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

并展示键盘:

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

对于DialogFragment,您可以在重写的onStart()中调用此方法,并且您可以使用getDialog().getWindow()作为getActivity().getWindow()的替代方法。 - Mr-IDE

10

showSoftInput 对我来说根本不起作用。

我发现我需要设置输入模式:(在清单中的 Activity 组件中)

android:windowSoftInputMode="stateVisible" 

8

以下是我从 Square 得到的更可靠的解决方案:

fun View.focusAndShowKeyboard() {
   /**
    * This is to be called when the window already has focus.
    */
   fun View.showTheKeyboardNow() {
       if (isFocused) {
           post {
               // We still post the call, just in case we are being notified of the windows focus
               // but InputMethodManager didn't get properly setup yet.
               val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
               imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
           }
       }
   }

   requestFocus()
   if (hasWindowFocus()) {
       // No need to wait for the window to get focus.
       showTheKeyboardNow()
   } else {
       // We need to wait until the window gets focus.
       viewTreeObserver.addOnWindowFocusChangeListener(
           object : ViewTreeObserver.OnWindowFocusChangeListener {
               override fun onWindowFocusChanged(hasFocus: Boolean) {
                   // This notification will arrive just before the InputMethodManager gets set up.
                   if (hasFocus) {
                       this@focusAndShowKeyboard.showTheKeyboardNow()
                       // It’s very important to remove this listener once we are done.
                       viewTreeObserver.removeOnWindowFocusChangeListener(this)
                   }
               }
           })
   }
}

代码来源于这里


使用观察者似乎是处理焦点延迟的更明智的方式,但我无法使其工作... - vctls
onWindowFocusChanged方法中删除if语句对我有用。谢谢。 - Yunis Rasulzade

8

只需在EditText视图中添加此行:

android:isScrollContainer="true"

然后,TADA - 键盘自动弹出了!

我也遇到过类似的问题,并发现了这个简单而奇怪的解决方案。

就像 user3392439 在这里提到的那样,键盘在聚焦时出现与 XML 文件中滚动组件的存在方式有些奇怪的联系。

即使同一 XML 中包含了另一个包含上述行的 EditText 视图,无论当前聚焦哪个 EditText,键盘都会出现。

如果您的 XML 文件中至少有一个包含滚动组件的可见视图,则键盘将在聚焦时自动出现。

如果没有滚动组件,则需要点击 EditText 才能使键盘出现。


这很奇怪,但绝对有效 - 我试图从点击处理程序中调用requesFocus(),除了显式的showSoftInput SHOW_FORCED之外,这是唯一的方法。 - drew
天啊,谢谢你。我不知道为什么它能够运行,但我已经在来自不同制造商的8个设备上进行了测试,每次都成功了! - Antonio Vlasic
谢谢,@Waldmann,只有你的答案完美地解决了问题!! - Happy Singh
对我来说不起作用。 - Vitaly

6
相信还是不相信,我遇到的软键盘问题得到解决,是因为我发现活动动画可以禁用软键盘。当你使用intent调用时,可以使用以下代码来禁用动画:
i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);

并且
overridePendingTransition(0, 0);

它可以隐藏软键盘,但没有办法显示它。

6
我将所有内容组合在这里,对我来说它有效:
public static void showKeyboardWithFocus(View v, Activity a) {
    try {
        v.requestFocus();
        InputMethodManager imm = (InputMethodManager) a.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
        a.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

6

我在各种不同的情况下遇到了同样的问题,我找到的解决方案在某些情况下起作用,但在其他情况下则无效。因此,这里有一个综合解决方案,可以解决我发现的大多数情况:

public static void showVirtualKeyboard(Context context, final View view) {
    if (context != null) {
        final InputMethodManager imm =  (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        view.clearFocus();

        if(view.isShown()) {
            imm.showSoftInput(view, 0);
            view.requestFocus();
        } else {
            view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                @Override
                public void onViewAttachedToWindow(View v) {
                    view.post(new Runnable() {
                        @Override
                        public void run() {
                            view.requestFocus();
                            imm.showSoftInput(view, 0);
                        }
                    });

                    view.removeOnAttachStateChangeListener(this);
                }

                @Override
                public void onViewDetachedFromWindow(View v) {
                    view.removeOnAttachStateChangeListener(this);
                }
            });
        }
    }
}

6

对我有用。你也可以尝试使用以下方法显示键盘:

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

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