Compose中快捷监听软键盘收起弹出状态方法(兼容Android各个版本)

非compose方法监听软键盘收起

在我们开发compose项目之前就有很多获取软键盘状态的方法,比如如下法1:

 fun getImeVisible(activity: Activity, callback: WindowsKeyboardCallback? = null) { //判断软键盘是否收起
        ViewCompat.setOnApplyWindowInsetsListener(activity.window.decorView) { _, insets ->
            val imeVisible = insets.isVisible(WindowInsetsCompat.Type.ime())
            val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
            callback?.onKeyboardChanged(imeVisible, imeHeight)
            WindowInsetsCompat.CONSUMED
        }
    }

但是这种不适合navigation的多页面路由中使用判断,会导致状态栏显示异常。
方法二:

fun Activity.listenForKeyboardVisibilityChange(callback: (Boolean) -> Unit) {
    val rootView = window.decorView.findViewById<View>(android.R.id.content)
    rootView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        private val rect = Rect()
        private var isKeyboardVisible = false

        override fun onGlobalLayout() {
            rootView.getWindowVisibleDisplayFrame(rect)
            val screenHeight = rootView.rootView.height
            val keyboardHeight = screenHeight - rect.bottom

            val isVisible = keyboardHeight > screenHeight * 0.15 // 判断键盘高度是否超过屏幕高度的 15%

            if (isVisible != isKeyboardVisible) {
                isKeyboardVisible = isVisible
                callback(isVisible)
            }
        }
    })
}

在compose中监听软键盘收起状态

    val imeVisible = WindowInsets.Companion.isImeVisible
    LaunchedEffect(WindowInsets.isImeVisible) {
        if (!imeVisible) {
            //软键盘收起
            onSubmit.invoke()
        }
    }

  只需要如上的判断既可以监听软键盘状态,而且不会对页面造成影响,可以说是非常简单了,(效果图就不搞了)觉得对你有帮助的也请点个收藏谢谢!
  今天同事在测试的时候发现了问题,在Android10(对应29)手机上这个方法不起作用,下面是我最终修改后的代码,做了适配:

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun imeVisible(): State<Boolean> {
    val isImeVisible = remember { mutableStateOf(false) }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        isImeVisible.value = WindowInsets.isImeVisible
    }else {
        val view = LocalView.current
        DisposableEffect(view) {
            val onGlobalListener = ViewTreeObserver.OnGlobalLayoutListener {
                val rect = Rect()
                view.getWindowVisibleDisplayFrame(rect)
                val screenHeight = view.rootView.height
                val keypadHeight = screenHeight - rect.bottom
                isImeVisible.value = keypadHeight > screenHeight * 0.15
            }
            view.viewTreeObserver.addOnGlobalLayoutListener(onGlobalListener)
            onDispose {
                view.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalListener)
            }
        }
    }

    return isImeVisible
}

  使用如下:

val imeVisible = imeVisible().value
    LaunchedEffect(imeVisible) {
        if (!imeVisible) {
            onSubmit.invoke()
        }
    }

使用前提

在这里插入图片描述

if (!view.isInEditMode) {
        SideEffect {
            val window = (view.context as Activity).window
            val windowController = WindowCompat.getInsetsController(window, view)
            //需要添加这一行代码
            WindowCompat.setDecorFitsSystemWindows(window, false)
            windowController.systemBarsBehavior =
                WindowInsetsControllerCompat.BEHAVIOR_DEFAULT
            windowController.show(WindowInsetsCompat.Type.statusBars())
        }
    }
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪の星空朝酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值