Compose中快捷监听软键盘收起弹出状态方法
非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()
}
}
版权声明:本文为Tobey_r1原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。