ChatGPT解决这个技术问题 Extra ChatGPT

使用 Kotlin 关闭/隐藏 Android 软键盘

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

有一个热门问题 Close/hide the Android Soft Keyboard关于在 Java 中执行此操作,但据我了解,应该有 Kotlin 的替代版本。我该怎么做?


G
Gunhan

在您的活动、片段中使用以下实用程序函数来隐藏软键盘。

(*) 更新最新的 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()

您会在应用程序中的哪个位置推荐这三个功能?
@Dan 我将这些函数保存在我的 ContextExtensions.kt 文件中,但您可以将它们保存在您认为合适的任何地方。
这对我来说非常有效。有趣的是,当应用程序在物理设备上运行时,我只需要此代码。在模拟器 (AVD) 上,键盘就像一个好的键盘一样自行消失。
出于某种原因,当我将它们放在 ContextExtensions.kt 文件中时,我似乎无法从我的 Fragments 等中访问它们。我需要在 ContextExtensions 类中设置一些特殊的东西,以使它们可以在整个应用程序中访问?
天哪,非常感谢。来自iOS,对我来说这甚至是一个问题似乎很荒谬,但你的解决方案是我见过的最干净的。谢谢!
J
Josh Correia

我认为我们可以稍微改进一下Viktor's answer。基于它始终附加到 View,会有上下文,如果有上下文,则有 InputMethodManager

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

在这种情况下,上下文自动意味着视图的上下文。你怎么看?


我想将此方法添加到一个实用程序类中,那么如何从活动/片段/适配器中调用此方法?
很好地使用例如 editText.hideKeybord() editText 可以替换为任何视图。
有没有办法把它放在一个单独的类中,以便在整个应用程序中都可以访问它?
K
Kaushik

只需在您的活动中覆盖此方法。它也将自动在其子片段中工作......

在 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);
}

在科特林

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)
    }

m
michal.z

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);
}

S
Seddiq Sorush

在您的 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()
     }

A
Andrew Fan

创建一个名为 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 )

M
MeLean

我没有看到 Kotlin 扩展函数的这个变体:

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

它的好处是可以从每个 CustomView 以及每次单击或触摸侦听器中调用此扩展函数


像魅力一样工作
V
Viktor Yakunin

您可以使用 Anko 让生活更轻松,因此该行将是:

inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)

或者更好地创建扩展功能:

fun View.hideKeyboard(inputMethodManager: InputMethodManager) {
    inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
}

并这样称呼它:

view?.hideKeyboard(activity.inputMethodManager)

我们必须使用哪个 Anko lib?因为它不适合我
inputMethodManager 未建立
M
MRazaImtiaz

虽然有很多答案,但这个答案与 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)。创建 LifeCycleObserver 类 创建一个类 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)
         )
     )

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

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


K
Kaushik

这是我在 Kotlin for Fragment 中的解决方案。将它放在按钮的 setOnClickListener 内。

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

S
Scooter

我在这里找到了适合我的答案:http://programminget.blogspot.com/2017/08/how-to-close-android-soft-keyboard.html

val inputManager:InputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.hideSoftInputFromWindow(currentFocus.windowToken, InputMethodManager.SHOW_FORCED)

K
Kavin Varnan

这适用于 API 26。

val view: View = if (currentFocus == null) View(this) else currentFocus
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)

Y
Yilmaz

编写一个隐藏键盘的函数:

private fun hideKeyboard(){
        // since our app extends AppCompatActivity, it has access to context
        val imm=getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        // we have to tell hide the keyboard from what. inorder to do is we have to pass window token
        // all of our views,like message, name, button have access to same window token. since u have button
        imm.hideSoftInputFromWindow(button.windowToken, 0)

       // if you are using binding object
       // imm.hideSoftInputFromWindow(binding.button.windowToken,0)

    }

您必须在需要的任何地方调用此函数


A
Akbolat SSS

感谢@Zeeshan Ayaz 这是一个稍微改进的版本

因为 'currentFocus' 可以为空,我们最好使用 Kotlin 的 ?.let 来检查它

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

j
jo jo

您可以使用波纹管代码,我在我的片段中编写波纹管代码:

private val myLayout = ViewTreeObserver.OnGlobalLayoutListener {
    yourTextView.isCursorVisible = KeyboardTool.isSoftKeyboardShown(myRelativeLayout.rootView)
}

然后在 fragmentonViewCreated 中:

......
super.onViewCreated(view, savedInstanceState)
myRelativeLayout.viewTreeObserver.addOnGlobalLayoutListener(myLayout)
......

onDestroyView 中也使用:

override fun onDestroyView() {
    super.onDestroyView()
 myRelativeLayout.viewTreeObserver.removeOnGlobalLayoutListener(myLayout)
}

和:

object KeyboardTool {
    fun isSoftKeyboardShown(rootView: View): Boolean {
        val softKeyboardHeight = 100
        val rect = Rect()

        rootView.getWindowVisibleDisplayFrame(rect)

        val dm = rootView.resources.displayMetrics
        val heightDiff = rootView.bottom - rect.bottom
        return heightDiff > softKeyboardHeight * dm.density
    }
}

C
Chienmin Lee

Kotlin 我使用以下代码:

导入 splitties.systemservices.inputMethodManager

inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0)


F
FABiO

您可以在 Kotlin 中使用函数扩展。如果您需要在 Fragment 中制作活动,请用 Fragment 替换活动。

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