【问题标题】:Close/hide the Android Soft Keyboard with Kotlin使用 Kotlin 关闭/隐藏 Android 软键盘
【发布时间】:2017-06-07 00:27:09
【问题描述】:

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

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

【问题讨论】:

    标签: android android-softkeyboard kotlin


    【解决方案1】:

    写一个函数来隐藏键盘:

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

    你必须在任何你需要的地方调用这个函数

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 工作就像一个魅力
      【解决方案3】:

      虽然有很多答案,但这个答案与 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)
               )
           )
      

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

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

        • 我想在一个实用程序类中添加这个方法,那么如何从activity/fragment/adapter调用这个方法??
        • 很好用例如editText.hideKeybord()editText 可以替换为任何视图。
        • 有没有办法将它放在一个单独的类中,以便在整个应用程序中都可以访问它?
        【解决方案5】:

        科特林 我使用下面的代码:

        导入 splitties.systemservices.inputMethodManager

        inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0)

        【讨论】:

          【解决方案6】:

          在您的活动、片段中使用以下实用功能来隐藏软键盘。

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

          无论您在对话框片段和/或活动等中的代码如何,这都会关闭键盘。

          在 Activity/Fragment 中的使用:

          hideKeyboard()
          

          【讨论】:

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

          这是我在 Kotlin 中针对 Fragment 的解决方案。将其放在按钮的setOnClickListener 内。

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

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

              【解决方案9】:

              感谢@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)
              }
              

              【讨论】:

                【解决方案10】:

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

                【讨论】:

                  【解决方案11】:

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

                  【讨论】:

                    【解决方案12】:

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

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

                    然后在onViewCreatedfragment 中:

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

                    【讨论】:

                      【解决方案13】:

                      我在这里找到了适合我的答案: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)
                      

                      【讨论】:

                        【解决方案14】:

                        这适用于 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)
                        

                        【讨论】:

                          【解决方案15】:

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

                          【讨论】:

                            【解决方案16】:

                            您可以使用 Anko 让生活变得更轻松,所以这行代码是:

                            inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
                            

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

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

                            然后这样称呼它:

                            view?.hideKeyboard(activity.inputMethodManager)
                            

                            【讨论】:

                            • 我们必须使用哪个 Anko 库?因为它不适合我
                            • inputMethodManager 未建立
                            猜你喜欢
                            • 2015-09-04
                            • 2014-07-19
                            • 2012-01-21
                            • 2013-12-09
                            • 1970-01-01
                            • 2022-12-14
                            • 2011-02-17
                            • 2012-07-22
                            • 2014-04-07
                            相关资源
                            最近更新 更多