简体   繁体   English

软件键盘与 Jetpack Compose 视图的内容重叠

[英]Software keyboard overlaps content of jetpack compose view

Suppose I have some activity with a jetpack-compose content假设我有一些关于 jetpack-compose 内容的活动

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ScrollableColumn(
                modifier = Modifier
                    .fillMaxSize()
                    .border(4.dp, Color.Red)
            ) {
                val (text, setText) = remember { mutableStateOf("") }

                TextField(
                    value = text,
                    onValueChange = setText,
                    label = {},
                    modifier = Modifier
                        .fillMaxWidth()
                )

                for (i in 0..100) {
                    Text("Item #$i")
                }
            }
        }
    }

}

If I were to launch this activity and focus on the TextField a software keyboard would pop up.如果我要启动此活动并专注于 TextField,则会弹出一个软件键盘。

The interface, however, would not react to it.但是,界面不会对此做出反应。 ScrollableColumn's bottom border ( .border(4.dp, Color.Red) ) would not be visible, as well as 100th item ( Text("Item #$i") ). ScrollableColumn 的底部边框 ( .border(4.dp, Color.Red) ) 以及第 100 个项目 ( Text("Item #$i") ) 将不可见。

In other words, software keyboard overlaps content.换句话说,软件键盘与内容重叠。

How can I make jetpack compose respect visible area changes (due to software keyboard)?如何让 Jetpack Compose 尊重可见区域变化(由于软件键盘)?

You can use the standard android procedure, but I don't know if a Compose specific way exists.您可以使用标准的 android 程序,但我不知道是否存在 Compose 特定方式。

If you set the SoftInputMode to SOFT_INPUT_ADJUST_RESIZE , the Layout will resize on keyboard change.如果将 SoftInputMode 设置为SOFT_INPUT_ADJUST_RESIZE ,则布局将在键盘更改时调整大小。

class YourActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        
        setContent { /* Composable Content */ }
    }
}

otherwise, you could use the flags in the manifest.否则,您可以使用清单中的标志。 See here for more information: Move layouts up when soft keyboard is shown?有关更多信息,请参见此处: 显示软键盘时向上移动布局?

I faced the same problem.我遇到了同样的问题。

Use OnGlobalLayoutListener which will observe the actual IME rect size and will be triggered when the soft keyboard is fully visible.使用OnGlobalLayoutListener将观察实际的 IME 矩形大小,并在软键盘完全可见时触发。

Worked solution for me:为我工作的解决方案:

val bringIntoViewRequester = remember { BringIntoViewRequester() }
val scope = rememberCoroutineScope()
val view = LocalView.current
DisposableEffect(view) {
    val listener = ViewTreeObserver.OnGlobalLayoutListener {
        scope.launch { bringIntoViewRequester.bringIntoView() }
    }
    view.viewTreeObserver.addOnGlobalLayoutListener(listener)
    onDispose { view.viewTreeObserver.removeOnGlobalLayoutListener(listener) }
}
TextField(
    modifier = Modifier.bringIntoViewRequester(bringIntoViewRequester),
    ...
)

Origin here 原产地在这里

You can use Accompanist's inset library https://google.github.io/accompanist/insets您可以使用 Accompanist 的 inset 库https://google.github.io/accompanist/insets

first use ProvideWindowInsets at the root of your composable hierarchy most of the time below your app theme compose and set windowInsetsAnimationsEnabled true大多数情况下,首先在可组合层次结构的根部使用ProvideWindowInsets在您的应用程序主题下方编写并设置windowInsetsAnimationsEnabled true

ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
// content  }

The use navigationBarsWithImePadding() modifier on TextField在 TextField 上使用navigationBarsWithImePadding()修饰符

OutlinedTextField(
// other params,
modifier = Modifier.navigationBarsWithImePadding() )

Finaly make sure to call WindowCompat.setDecorFitsSystemWindows(window, false) from your activity(inside onCreate ).最后确保从您的活动(在onCreate 内)调用WindowCompat.setDecorFitsSystemWindows(window, false )。 If you want Software keyboard on/off to animate set your activity's windowSoftInputMode adjustResize in AndroidManifests如果您希望软件键盘开/关设置动画,请在 AndroidManifests 中设置您的活动的windowSoftInputMode adjustResize

<activity
  android:name=".MyActivity"
  android:windowSoftInputMode="adjustResize">

Besides Compose, no external libraries are needed for this now.除了 Compose,现在不需要外部库。 Set android:windowSoftInputMode=adjustResize on the activity in your manifest file在清单文件中的活动上设置android:windowSoftInputMode=adjustResize

eg例如

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application>
        <activity
            android:name=".MyActivity"
            android:windowSoftInputMode="adjustResize"/>
    </application>

</manifest>

Then for the composable that you want the UI to react to, you can use Modifier.imePadding() which reacts to IME visibility然后对于您希望 UI 做出反应的可组合项,您可以使用Modifier.imePadding()来对 IME 可见性做出反应

Box(Modifier.imePadding()) {
  // content
}

I came up with idea of using accompanist insets library.我想出了使用伴奏插入库的想法。

Someone could be interested because my approach does not modificate the contents of an application.有人可能会感兴趣,因为我的方法不会修改应用程序的内容。

I link my post below:我在下面链接我的帖子:

(Compose UI) - Keyboard (IME) overlaps content of app (Compose UI) - 键盘 (IME) 与应用程序的内容重叠

If you want your TextField scroll up when keyboard appears.如果您希望 TextField 在键盘出现时向上滚动。 The following it work for me.以下对我有用。 You need to add these你需要添加这些

class YourActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    
    setContent { /* Composable Content */ }
}

And add this to your app/build.gradle并将其添加到您的 app/build.gradle

implementation "com.google.accompanist:accompanist-insets-ui:0.24.7-alpha"

In my case just adding android:windowSoftInputMode="adjustResize" to activity was enough to solve the problem.在我的情况下,只需将android:windowSoftInputMode="adjustResize"添加到活动中就足以解决问题。
It depends on how you build your UI.这取决于您如何构建 UI。 If yours screen's root is a vertically scrollable container or a Box, the keyboard resize might get managed automatically.如果您的屏幕的根是可垂直滚动的容器或 Box,则键盘调整大小可能会自动管理。

Use the modifier imePadding() .使用修饰符imePadding() This will allow the specific compositions to adjust themselves when the keyboard pops up.这将允许特定的组合在键盘弹出时自行调整。 This does not require you to set any flag on the activity这不需要您在活动上设置任何标志

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM