【问题标题】:Software keyboard overlaps content of jetpack compose view软件键盘与 jetpack compose 视图的内容重叠
【发布时间】:2020-09-24 16:15:26
【问题描述】:

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

}

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

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

换句话说,软键盘与内容重叠。

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

【问题讨论】:

    标签: android android-layout android-jetpack-compose


    【解决方案1】:

    你可以使用标准的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 */ }
        }
    }
    

    否则,您可以使用清单中的标志。浏览此处获取更多信息: Move layouts up when soft keyboard is shown?

    【讨论】:

    • 它成功了,android:windowSoftInputMode="adjustResize"(你暗示的那个)也有效。非常感谢!
    • 在清单中设置标志与在代码中设置它是一样的,我猜只是你的偏好。
    • 我认为这只是在键盘弹出时设置底部插入,但在键盘弹出后内容仍然不能完全可见,除非ScrollableColumn 会保持焦点项目滚动到可见位置。
    • 谢谢,但是在键盘上点击下一个按钮,文本字段仍然不可见,即可滚动列没有滚动,知道如何解决这个问题吗?
    • @Hoby 我认为你必须手动滚动,你可以通过测量 Column 中的所有内容来计算位置,然后将滚动状态设置为焦点元素的相对位置。
    【解决方案2】:

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

    首先在可组合层次结构的根部使用 ProvideWindowInsets,大部分时间在应用主题下方组合并设置 windowInsetsAnimationsEnabled true

    ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
    // content  }
    

    在 TextField 上使用 navigationBarsWithImePadding() 修饰符

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

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

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

    【讨论】:

    • 我只在 Jetpack 组合 TextField 中使用了 ProvideWindowInsets(windowInsetsAnimationsEnabled = true),如答案中所述,它对我有用。
    • 对我来说非常好用,第一个答案对我来说还不够,因为我在文本字段下方有一些东西,我也想在键盘上方移动。
    • 它不适用于滚动布局
    【解决方案3】:

    我想出了使用伴奏 insets 库的想法。

    有人可能会感兴趣,因为我的方法不会修改应用程序的内容。

    我在下面链接我的帖子:

    (Compose UI) - Keyboard (IME) overlaps content of app

    【讨论】:

      猜你喜欢
      • 2022-10-25
      • 2021-04-10
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2013-03-14
      相关资源
      最近更新 更多