在 Jetpack Compose 中确定键盘的存在并相应地更改布局 [英] Determine keyboard presence and change layout accordingly in Jetpack Compose

查看:229
本文介绍了在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆