如何在程序中编程设置EditText的焦点(并显示键盘)

235

我有一个布局,其中包含一些像这样的视图:

<LinearLayout>
<TextView...>
<TextView...>
<ImageView ...>
<EditText...>
<Button...>
</linearLayout>

如何在程序中设置焦点(显示键盘)到我的EditText上?

我尝试了这个方法,当我正常启动我的Activity时它有效,但当我在TabHost中启动它时不起作用。

txtSearch.setFocusableInTouchMode(true);
txtSearch.setFocusable(true);
txtSearch.requestFocus();

http://www.android-ios-tutorials.com/93/android-show-hide-soft-keyboard-programmatically/ - Houcine
可能是重复的问题:如何在EditText获得焦点时显示软键盘 - raukodraug
21个回答

435

5
只有在我正常启动我的活动时它才能工作,但当我在TabHost上启动我的活动时,它就无法工作了。 - Houcine
37
这个不起作用。这个可以用: InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); 对我有效。 - Günay Gültekin
13
“这行不通,兄弟。” 在某些情况下,您需要从postDelayed()异步调用此代码。我曾遇到这样一种情况:当用户在对话框上按下“确定”后,我需要打开键盘。而当对话框关闭时,它会干扰焦点。因此,我从postDelayed()中调用了上面的代码。它在对话框关闭后执行。收益。 - Danylo Volokh
2
答案获得了237个赞,而“它不起作用兄弟”的评论则获得了62个赞。我测试过了,得出了自己的意见,它完美地运行! - Daniel
2
只是分享一下经验:我刚刚将代码添加到当前应用程序项目中的四个不同片段中。在前三个片段中,代码完美运行。但在最后一个片段中,直到我使用Kotlin协程从onViewCreated开始延迟100毫秒启动代码后,才显示键盘。 - Nantoka
显示剩余11条评论

182

使用:

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

24
在尝试了其他5种方法后,这是唯一一个适用于我的(从View子类中)的方法。 - William
16
这个建议导致键盘被固定,即使字段失去焦点。 - untill
3
是的,这对我也起作用,但imm.showSoftInput()不起作用。 - Spark.Bao
13
虽然这种方法确实有效,但是它有一个缺点,用主页按钮(硬件)退出应用程序会让屏幕上的键盘保留显示。尽管在主屏幕上无用,但你仍需要按返回按钮(硬件)隐藏键盘。 - Adrien Horgnies
@AdrienHorgnies 你是对的。一个可能的解决方案是重写 onPause 或 onStop 然后隐藏键盘。 - Alexandre Prazeres
显示剩余4条评论

61

这对我有用,感谢ungalcrys

显示键盘:

editText = (EditText)findViewById(R.id.myTextViewId);
editText.requestFocus();
InputMethodManager imm = (InputMethodManager)getSystemService(this.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY);

隐藏键盘:

InputMethodManager imm = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

3
唯一完整的解决方案。谢谢。 - korro

56
final EditText tb = new EditText(this);
tb.requestFocus();
tb.postDelayed(new Runnable() {
    @Override
    public void run() {
        InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.showSoftInput(tb, InputMethodManager.SHOW_IMPLICIT);
    }
}, 1000);

1
我必须这样做才能在onResume()中显示它。如果没有延迟,使用本主题中描述的每个解决方案都不会发生任何事情。 - FranticRock
2
那就是答案,我一直在寻找的答案。尽管如此,您不一定需要整个 2 秒的延迟。我尝试了只使用 150 毫秒,也可以正常工作。 - Rubberduck
6
谢谢!即使是0毫秒 (tb.post({ showKeyboard(tb) })), 这也有效。请注意,我们需要一个 EditText 视图(tb),而不是片段视图。 - CoolMind

44

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

我发现我需要设置输入模式:android:windowSoftInputMode="stateVisible"(在清单文件中的 Activity 组件中设置)

希望这能帮到你!


5
这只是在活动启动时显示了键盘。 - William
1
太棒了 :) 尝试了很多答案,但只有这个才能让它工作 :) 非常感谢。 - Srikanth
非常被低估的答案 - Avinash R
完美的答案。只需使用“editText.requestFocus()”即可运行。谢谢。 - AVJ

34

以下是如何创建用于显示和隐藏软键盘的Kotlin扩展:

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

fun View.hideKeyboard() {
  val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
}

然后你只需要这样做:

editText.showKeyboard()
// OR
editText.hideKeyboard()

4
与其它方案相比,这是一个更好的解决方案。 - d-feverx
2
这个方法在2021年3月对我有效。我是通过Handler(Looper.getMainLooper()).postDelayed( { ... }, 1000)实现的。 - Nick M
1
这个很好用。另外,如果包含调用showKeyboard()的View的Fragment被dismissed,键盘会自动关闭。我在dismiss Fragment时键盘没有关闭时使用imm遇到了麻烦。 - Tyler Wood
非常优雅。这个解决方案的优越性是显而易见的。 - Cyrill

9
我建议使用LifecycleObserver,它是使用Lifecycle-Aware组件处理生命周期Android Jetpack的一部分。
我想在Fragment / Activity出现时打开和关闭键盘。首先,为EditText定义两个扩展函数。您可以将它们放在项目中的任何位置:
fun EditText.showKeyboard() {
    requestFocus()
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

fun EditText.hideKeyboard() {
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(this.windowToken, 0)
}

然后定义一个LifecycleObserver,在Activity/Fragment达到onResume()onPause时打开和关闭键盘:

class EditTextKeyboardLifecycleObserver(private val editText: WeakReference<EditText>) :
    LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun openKeyboard() {
        editText.get()?.postDelayed({ editText.get()?.showKeyboard() }, 100)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun closeKeyboard() {
        editText.get()?.hideKeyboard()
    }
}

然后将以下行添加到您的任何Fragment / Activity中,您可以多次重复使用LifecycleObserver。例如,对于Fragment:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

    // inflate the Fragment layout

    lifecycle.addObserver(EditTextKeyboardLifecycleObserver(WeakReference(myEditText)))

    // do other stuff and return the view

}

7
这是一个KeyboardHelper类,用于隐藏和显示键盘。
import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;

/**
 * Created by khanhamza on 06-Mar-17.
 */

public class KeyboardHelper {
public static void hideSoftKeyboard(final Context context, final View view) {
    if (context == null) {
        return;
    }
    view.requestFocus();
    view.postDelayed(new Runnable() {
        @Override
        public void run() {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}, 1000);
}

public static void hideSoftKeyboard(final Context context, final EditText editText) {
    editText.requestFocus();
    editText.postDelayed(new Runnable() {
        @Override
        public void run() {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}, 1000);
}


public static void openSoftKeyboard(final Context context, final EditText editText) {
    editText.requestFocus();
    editText.postDelayed(new Runnable() {
        @Override
        public void run() {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
}, 1000);
}
}

6

将此代码放到onResume()方法中。

binding.etxtSearch.isFocusableInTouchMode = true
binding.etxtSearch.isFocusable = true
binding.etxtSearch.requestFocus() 
val inputMethodManager = context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(binding.etxtSearch, InputMethodManager.SHOW_IMPLICIT)

3
最初的回答:
我尝试了很多方法,但似乎都不起作用,可能是因为我正在使用从片段到包含EditText的活动的共享转换。
顺便说一下,我的EditText也被包装在LinearLayout中。
我添加了一个轻微的延迟来请求焦点,并且以下代码对我有用:(Kotlin)
 et_search.postDelayed({
     editText.requestFocus()

     showKeyboard()
 },400) //only 400 is working fine, even 300 / 350, the cursor is not showing

展示键盘()

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

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