在 Jetpack Compose 中确定键盘的存在并相应地更改布局 [英] Determine keyboard presence and change layout accordingly in Jetpack Compose
问题描述
当我点击 TextField 时,我需要向上滚动 UI 以向用户显示登录按钮,而不是将其隐藏在键盘后面.
我正在使用 RelocationRequester.
我用它来检测键盘显示/隐藏事件:
有趣的 listenKeyboard() {val activityRootView =(requireActivity().findViewById(android.R.id.content) as ViewGroup).getChildAt(0)activityRootView.viewTreeObserver.addOnGlobalLayoutListener(对象:ViewTreeObserver.OnGlobalLayoutListener {私有变量 wasOpened = false私人 val DefaultKeyboardDP = 100私人 val EstimatedKeyboardDP =默认键盘DP + 48私有 val r: Rect = Rect()覆盖 fun onGlobalLayout() {val 估计键盘高度 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,EstimatedKeyboardDP.toFloat(),activityRootView.resources.displayMetrics).toInt()activityRootView.getWindowVisibleDisplayFrame(r)val heightDiff: Int = activityRootView.rootView.height - (r.bottom - r.top)val isShown = heightDiff >=估计键盘高度if (isShown == wasOpened) {返回}wasOpened = isShown键盘可见状态(显示)}})}
一旦键盘可见,我就会调用 relocationRequestor 的 combineIntoView().
coroutineScope.launch {延迟(250)relocationRequester.bringIntoView()}
它的行为是随机的,在某些设备上运行而不在其他设备上运行.有没有更好的解决方案来处理这个问题?
您可以使用 得到解决
When I click on TextField, I need to scroll UI upwards to show login button to the user and not hide it behind keyboard.
I am using RelocationRequester for the same.
I am using this for detecting keyboard show/hide event:
fun listenKeyboard() {
val activityRootView =
(requireActivity().findViewById<View>(android.R.id.content) as ViewGroup).getChildAt(0)
activityRootView.viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener {
private var wasOpened = false
private val DefaultKeyboardDP = 100
private val EstimatedKeyboardDP =
DefaultKeyboardDP + 48
private val r: Rect = Rect()
override fun onGlobalLayout() {
val estimatedKeyboardHeight = TypedValue
.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
EstimatedKeyboardDP.toFloat(),
activityRootView.resources.displayMetrics
)
.toInt()
activityRootView.getWindowVisibleDisplayFrame(r)
val heightDiff: Int = activityRootView.rootView.height - (r.bottom - r.top)
val isShown = heightDiff >= estimatedKeyboardHeight
if (isShown == wasOpened) {
return
}
wasOpened = isShown
keyboardVisibleState(isShown)
}
})
}
and once the keyboard is visible, I am calling the relocationRequestor's bringIntoView().
coroutineScope.launch {
delay(250)
relocationRequester.bringIntoView()
}
Its behaving randomly, working on some devices and not on others. Is there any better solution to deal with this issue?
You can use accompanist insets. You'll be able to check if keyboard is presented using LocalWindowInsets.current.ime.isVisible
or add .imePadding()
to your screen container.
This works great. But to make it work you'll have to disable window decor fitting:
This library does not disable window decor fitting. For your view hierarchy to able to receive insets, you need to make sure to call: WindowCompat.setDecorFitsSystemWindows(window, false) from your Activity. You also need to set the system bar backgrounds to be transparent, which can be done with our System UI Controller library.
If you don't want to do this, you will have to look for another solution.
Example in onCreate
:
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
ProvideWindowInsets {
ComposePlaygroundTheme {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxWidth()
.statusBarsPadding()
.navigationBarsWithImePadding()
.padding(10.dp)
) {
TextField(value = "", onValueChange = {})
Spacer(Modifier.weight(1f))
Button(onClick = {}) {
Text(text = "Proceed")
}
}
}
}
}
p.s. Also this won't help with lazy views: it's gonna decrease container size, but won't scroll to selected item. Waiting this issue to be resolved
这篇关于在 Jetpack Compose 中确定键盘的存在并相应地更改布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!