You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中软键盘可见性(打开/关闭)的监听问题

监听软键盘可见性变化的实现方案

使用ViewCompat.setOnApplyWindowInsetsListener()可以监听窗口内边距的变化,从中提取软键盘(IME)的显示/隐藏状态,具体实现如下:

核心实现逻辑

软键盘的显示或隐藏会触发窗口内边距的改变,通过监听WindowInsets中的IME类型参数,就能判断键盘状态的变化,同时记录上一次的状态,避免重复触发逻辑。

代码示例

在Activity中实现

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat

class MainActivity : AppCompatActivity() {
    private var lastImeVisible = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val rootView = findViewById<android.view.View>(android.R.id.content)
        ViewCompat.setOnApplyWindowInsetsListener(rootView) { view, insets ->
            val currentImeVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
            
            // 仅当状态发生变化时执行逻辑
            if (currentImeVisible != lastImeVisible) {
                lastImeVisible = currentImeVisible
                if (currentImeVisible) {
                    // 软键盘显示时的处理逻辑
                    println("软键盘已弹出")
                } else {
                    // 软键盘隐藏时的处理逻辑
                    println("软键盘已收起")
                }
            }

            // 必须返回处理后的insets,否则会影响布局的内边距适配
            ViewCompat.onApplyWindowInsets(view, insets)
        }
    }
}

在Fragment中实现

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment

class ExampleFragment : Fragment() {
    private var lastImeVisible = false

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
            val currentImeVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
            
            if (currentImeVisible != lastImeVisible) {
                lastImeVisible = currentImeVisible
                if (currentImeVisible) {
                    // 键盘显示逻辑
                } else {
                    // 键盘隐藏逻辑
                }
            }

            ViewCompat.onApplyWindowInsets(v, insets)
        }
    }
}

关键注意点

  • 务必返回ViewCompat.onApplyWindowInsets(view, insets),否则会导致布局无法正确响应系统窗口的内边距变化
  • 优先给根View设置监听器,确保能捕获全局的窗口内边距变动
  • 记录lastImeVisible是为了过滤掉非键盘引起的内边距变化(比如系统导航栏的显示/隐藏)

内容的提问来源于stack exchange,提问作者JayDee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:10:30