EditText请求焦点无效

38

我有一个EditText和一个Button。 点击按钮后,我希望打开EditText键盘,并在同时将焦点请求设置到EditText上,以便用户可以直接开始在键盘上输入文本并在EditText中显示。但是,在我的情况下,当我点击按钮时,它会打开键盘,但不会将焦点设置在EditText上,因此用户必须再次点击EditText才能写入其中。出了什么问题?有任何帮助或建议。

点击按钮的代码:

m_SearchEditText.requestFocus();
InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInputFromWindow(m_SearchEditText.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);

https://dev59.com/j2Yq5IYBdhLWcg3woCC7 - Muhammad Aamir Ali
有时候,当你已经把焦点放在editText上,再次尝试设置焦点时,编辑光标可能不会移动到所需的editText。解决方案:移除焦点并重新请求焦点。 - Sharanabasu Angadi
尝试这个经过测试并在Android Pie上工作的方法。 - Swapnil Thube
1
Rahul -- @RobertoAllende 的回答似乎是最正确的。如果您同意,请选择它作为正确答案。 - JohnnyLambada
16个回答

57

确保EditText能够在触摸模式下获取焦点。您可以通过两种方式来实现。

XML中:

android:focusableInTouchMode="true"

在Java中:

view.setFocusableInTouchMode(true);

就我个人而言,我不信任这个参数的XML定义。我总是通过以下这两行代码请求焦点:

view.setFocusableInTouchMode(true);
view.requestFocus();

键盘应该自动弹出,无需调用InputMethodManager。

这在大多数情况下都有效。有一次它对我不起作用,因为由于相当重的处理,我已经丢失了对象的引用-确保这不是您的问题。


5
我有同样的问题,但这并没有解决我的问题。这似乎是一个常见的问题,却没有一个通用的解决方案。我尝试了其他人建议的几种方法,但对于我的情况似乎都不起作用。 - Chad
很惊讶这个问题没有更多的赞。我整天在 StackOverflow 上查找,这是唯一一个在我的 Activity 加载时将 EditText 视图设置为可聚焦的解决方案。现在我只需要弄清楚如何使用这个解决方案,除非用户点击它,否则不加载键盘。 - AdamHurwitz
2
这个回答虽然得票不高,但真是一颗宝石!运行得非常好! - sud007
在XML中,android:focusableInTouchMode="true"对我起了作用。 - qki

21
在我的情况下,通过在单击按钮并将焦点设置在另一个视图后添加处理程序,焦点可以回到所需的视图。
只需将以下内容放入您的代码中:
final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        lastview.getEditText().clearFocus();
                        m_SearchEditText.requestFocus();
                        InputMethodManager mgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);


                        mgr.showSoftInput(mLastNameET, InputMethodManager.SHOW_IMPLICIT);

                    }
                }, 100);

我希望这有所帮助。


1
不需要创建新的Handler,只需使用视图本身:lastview.getEditText().post(new Runnable....) - pauminku
1
什么是lastview? - r3dm4n
@r3dm4n -- 这是涉及EditText的变量名称。看一下Saleh答案的第5行就能看到它。 - JohnnyLambada

12

跟随saleh sereshki的回答和pauminku的评论,我正在使用:

m_SearchEditText.post(new Runnable() {
            @Override
            public void run() {
                m_SearchEditText.requestFocus();
            }
        });

Kotlin中等同于此的是:

m_SearchEditText.post { m_SearchEditText.requestFocus() }

1
完美运作,.post 让您可以将任何视图聚焦在屏幕上。大多数其他答案可能来自 Android 平台以通常的级联方式聚焦。 - Rowan Berry

9
在你的 manifest.xml 文件中编写如下内容:
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysVisible" />

onCreate()中调用m_SearchEditText.requestFocus()
或者
尝试:

if(m_SearchEditText.requestFocus()) {
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}

8
以下内容适用于我并应该有所帮助,具体步骤如下:
EditText yourEditText= (EditText) findViewById(R.id.yourEditText);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(yourEditText, InputMethodManager.SHOW_IMPLICIT);

1
我在这个问题上挣扎了很久,看了这个页面上的几个建议。最终找到了一个可行的方法。 - methodsignature
1
我在下面添加了一个Kotlin扩展版本:https://dev59.com/hmMm5IYBdhLWcg3wdu5V#52712915。 - methodsignature

5

这是极简主义的Kotlin扩展版本,因为我们应该假装这些对系统服务的晦涩调用并非必需:

fun EditText.requestKeyboardFocus() {
    val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

5
作为这个回答的扩展(由于身份原因,我没有将其添加为评论...),如果您想将延迟时间减少到零,请改用handler.post()。完整代码:
final Handler handler = new Handler();
handler.post(new Runnable() {
    @Override
    public void run() {
        lastview.getEditText().clearFocus();
        m_SearchEditText.requestFocus();
        InputMethodManager mgr = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);


        mgr.showSoftInput(mLastNameET, InputMethodManager.SHOW_IMPLICIT);
    }
});

@Matis Olocco,mLastNameET到底是什么?它是像EditText这样的视图对象类型,还是来自XML布局ID的EditText?因为这个方法只接受int,int作为参数。 - Khay
@Khay,你应该向原答案的作者提问。如果你读了我的回答,那么它只是对原答案的扩展。我没有把它写成评论,因为当时我还没有足够的积分。 - Matias Olocco

4
您需要两个XML属性来实现这一点:
android:focusable="true"
android:focusableInTouchMode="true"

将它们添加到EditText以及父布局中(任何包含这些视图的布局)。默认情况下,这些值为false,因此不会将焦点放在请求的视图上。
来源:https://developer.android.com/reference/android/view/View.html#attr_android:focusable 在基于复选框选择显示EditText后,通过代码动态添加下一个和上一个焦点。
希望这能有所帮助。

在API 19上,我只使用了android:focusableInTouchMode="true"和<requestFocus />,但键盘没有弹出。添加android:focusable="true"解决了这个问题。 - steven smith

3
为了使焦点聚集,您可以使用此函数。
editText.requestFocus()

关于EditText,可能会有两个不同的问题。一个是虽然EditText处于焦点状态,但键盘却不会自动弹出,这时你需要按照其他答案所说,手动打开键盘。另一个问题则是EditText根本没有获得焦点,也就是什么都没发生。

如果想要打开键盘,可以在requestFocus之后执行以下操作:

val manager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
manager?.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)

如果 EditText 完全没有焦点,请检查以下属性。在调用 requestFocus 之前,EditText 必须是可聚焦的、可见的、启用的、触摸模式下可聚焦的。请启用所有这些属性。
this.isFocusable = true
this.isFocusableInTouchMode = true
this.visibility = View.VISIBLE
this.isEnabled = true

最终,您可以使用这个Kotlin扩展为您完成所有这些操作:
fun EditText.focus() {
    this.isFocusable = true
    this.isFocusableInTouchMode = true
    this.visibility = View.VISIBLE
    this.isEnabled = true
    this.isCursorVisible = true
    this.post {
        (this.context as? Activity)?.runOnUiThread {
            this.requestFocus()
            val manager =
                this.context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
            manager?.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
        }
    }
}

0

有时请求焦点无法正常工作,但现在它可以正常工作了。

fun EditText.focus(activity: Activity) {
this.isFocusable = true
this.isFocusableInTouchMode = true
this.visibility = View.VISIBLE
this.isEnabled = true
this.isCursorVisible = true
this.post {
    activity?.runOnUiThread {
        this.requestFocus()
        val manager =
            this.context.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
        manager?.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
    }
}

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