软件键盘与 jetpack 组合视图的内容重叠

Nyc*_*cta 8 android android-layout android-jetpack-compose

假设我有一些关于 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")
                }
            }
        }
    }

}

Run Code Online (Sandbox Code Playgroud)

如果我要启动此活动并专注于 TextField,则会弹出一个软件键盘。

但是,界面不会对此做出反应。ScrollableColumn 的底部边框 ( .border(4.dp, Color.Red)) 以及第 100 项 ( Text("Item #$i"))将不可见。

换言之,软键盘与内容重叠。

我怎样才能让喷气背包 compose 尊重可见区域的变化(由于软件键盘)?

And*_*tor 47

除了 Compose 之外,现在不需要任何外部库。在清单文件中设置android:windowSoftInputMode=adjustResize活动

例如

<?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>
Run Code Online (Sandbox Code Playgroud)

然后,对于您希望 UI 做出反应的可组合项,您可以使用Modifier.imePadding()对 IME 可见性做出反应

Box(Modifier.imePadding()) {
  // content
}
Run Code Online (Sandbox Code Playgroud)


小智 23

您可以使用Accompanist的插入库https://google.github.io/accompanist/insets

大多数时候,首先在可组合层次结构的根部使用ProvideWindowInsets ,并在应用主题 compose 下面设置windowInsetsAnimationsEnabled true

ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
// content  }
Run Code Online (Sandbox Code Playgroud)

在 TextField 上使用navigationBarsWithImePadding()修饰符

OutlinedTextField(
// other params,
modifier = Modifier.navigationBarsWithImePadding() )
Run Code Online (Sandbox Code Playgroud)

最后确保从您的活动(在onCreate内)调用WindowCompat.setDecorFitsSystemWindows(window, false)。如果您希望软件键盘开/关动画,请在 AndroidManifests 中设置 Activity 的windowSoftInputMode adjustmentResize

<activity
  android:name=".MyActivity"
  android:windowSoftInputMode="adjustResize">
Run Code Online (Sandbox Code Playgroud)

  • 已弃用。请参阅/sf/answers/5182531511/ (2认同)

2ja*_*222 9

您可以使用标准的 android 程序,但我不知道是否存在 Compose 特定方式。

如果将 SoftInputMode 设置为SOFT_INPUT_ADJUST_RESIZE,则布局将在键盘更改时调整大小。

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

否则,您可以使用清单中的标志。有关更多信息,请参见此处: 显示软键盘时向上移动布局?

  • SOFT_INPUT_ADJUST_RESIZE 已弃用,有更新吗? (7认同)
  • 它做到了这一点,`android:windowSoftInputMode =“adjustResize”`(您暗示的)也有效。非常感谢! (3认同)
  • 我认为这只在键盘弹出时设置底部插图,但在键盘弹出后内容仍然无法完全可见,除非“ScrollableColumn”将使焦点项滚动到可见位置。 (3认同)
  • 谢谢,但在键盘上单击下一个按钮,文本字段仍然不可见,即可滚动列未滚动,知道如何解决这个问题吗? (2认同)

小智 5

使用修饰符imePadding()。这将允许特定的组合在键盘弹出时自行调整。这不需要您在活动上设置任何标志

  • `imePadding()` 还需要 `.fillMaxHeight()` (3认同)