关闭/隐藏Android软键盘(Kotlin实现)

112

我正在尝试用Kotlin编写一个简单的Android应用程序,我的布局中有一个EditText和一个Button。在编辑字段中输入内容并点击按钮后,我想隐藏虚拟键盘。

这里有一个关于Java如何实现的热门问题关闭/隐藏Android软键盘,但据我所知,Kotlin应该有另一种替代版本。我该怎么做呢?

19个回答

224

使用以下实用函数在您的活动(Activities)、片段(Fragments)中隐藏软键盘。

(*)更新至最新的 Kotlin 版本

fun Fragment.hideKeyboard() {
    view?.let { activity?.hideKeyboard(it) }
}

fun Activity.hideKeyboard() {
    hideKeyboard(currentFocus ?: View(this))
}

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

无论是在对话框片段还是活动等中,此操作将关闭键盘。

在活动/片段中的使用:

hideKeyboard()

1
你会建议这三个函数在应用程序中放置在哪里? - Dan
3
@Dan 我把这些函数放在我的ContextExtensions.kt文件中,但你可以将它们放在任何适合的地方。 - Gunhan
@CeH9 是的,越短越好。 - Gunhan
2
哇,非常感谢你的帮助。作为一个iOS开发者,我觉得这个问题很荒谬,但是你提供的解决方案是我见过最干净的。谢谢! - Ricky Padilla
无法在函数中使用它们,有关调用它们的任何帮助? - Karan Khurana
显示剩余5条评论

89

我认为我们可以稍微改进Viktor的答案。基于它总是被附加到一个View上,那么就会有上下文,如果有上下文,那就会有InputMethodManager

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

在这种情况下,上下文自动意味着视图的上下文。 你认为呢?


我想将这个方法添加到一个实用类中,然后如何从活动/片段/适配器中调用此方法? - chandani c patel
1
例如,我们可以使用editText.hideKeyboard()。其中的editText可以替换为任何视图。 - AndroLife
有没有一种方法可以将它放在一个单独的类中,以便在整个应用程序中都可以访问到它? - svguerin3

24

只需在您的活动中覆盖此方法即可。它也会自动在其子片段中起作用.....

使用JAVA语言

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (getCurrentFocus() != null) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
    return super.dispatchTouchEvent(ev);
}

在 Kotlin 中

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        if (currentFocus != null) {
            val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
        }
        return super.dispatchTouchEvent(ev)
    }

15

在你的 Activity 或 Fragment 中创建一个如下的函数:

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

假设您在与此Activity或Fragment相关的XML文件中有一个ID为your_button_id的按钮,因此,在按钮单击事件上:

    your_button_id.setOnClickListener{
       it.hideKeyboard()
     }

简单而准确 - Anju mohan

8

Peter的解决方案通过扩展View类的功能来整洁地解决了问题。另一种方法是扩展Activity类的功能,并将隐藏键盘的操作绑定到View的容器而不是View本身。

fun Activity.hideKeyboard() {
    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(findViewById(android.R.id.content).getWindowToken(), 0);
}

8

我没见过这种 Kotlin 扩展函数的变体:

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

这个扩展函数的好处在于它可以从每个自定义视图中调用,在每个点击或触摸监听器中也可以调用。


6
创建一个名为Utils的对象类:
object Utils {

    fun hideSoftKeyBoard(context: Context, view: View) {
        try {
            val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm?.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
        } catch (e: Exception) {
            // TODO: handle exception
            e.printStackTrace()
        }

    }
}

你可以在任何想要隐藏软输入键盘的类中使用此方法。我在我的BaseActivity中使用了它。
这里的视图是您在布局中使用的任何视图:
Utils.hideSoftKeyBoard(this@BaseActivity, view )

5
您可以使用Anko使生活更加轻松,这样这行代码就是:
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)

或许创建一个扩展函数更好:
fun View.hideKeyboard(inputMethodManager: InputMethodManager) {
    inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
}

然后像这样调用:

view?.hideKeyboard(activity.inputMethodManager)

我们应该使用哪个Anko库?因为它对我来说无法工作。 - Jéwôm'
inputMethodManager未找到。 - Jéwôm'

5
虽然有很多答案,但是这个答案与在KOTLIN中使用最佳实践相关,可以通过生命周期和扩展函数打开和关闭键盘。 1). 创建扩展函数创建一个名为EditTextExtension.kt的文件,并粘贴以下代码。
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)
 }

2). 创建生命周期观察者类 创建一个名为 EditTextKeyboardLifecycleObserver.kt 的类,并粘贴以下代码:

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

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

3). 接下来在 onViewCreated / onCreateView 中使用以下代码:

lifecycle.addObserver(
         EditTextKeyboardLifecycleObserver(
             WeakReference(mEditText) //mEditText is the object(EditText)
         )
     )

当用户打开片段或活动时,键盘将自动打开。

如果您遇到任何问题,请遵循解决方案,并随时在评论中提问。


4

这是我用 Kotlin 编写的 Fragment 解决方案。将其放置在按钮的 setOnClickListener 中。

val imm = context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager?
imm?.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)

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