软件键盘与jetpack撰写视图的内容重叠

问题描述 投票:0回答:10

假设我有一些与喷气背包撰写内容相关的活动

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")
                }
            }
        }
    }

}

如果我启动此活动并专注于文本字段,则会弹出一个软件键盘。

但是,界面不会对此做出反应。 ScrollableColumn 的底部边框 (

.border(4.dp, Color.Red)
) 以及第 100 项 (
Text("Item #$i")
) 将不可见。

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

如何使 jetpack compose 尊重可见区域的变化(由于软件键盘)?

android android-layout android-jetpack-compose
10个回答
52
投票

除了 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>

然后,对于您希望 UI 做出反应的可组合项,您可以使用

Modifier.imePadding()
来对 IME 可见性做出反应

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

36
投票

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

否则,您可以使用清单中的标志。浏览此处获取更多信息: 显示软键盘时向上移动布局?


23
投票

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

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

ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
// content  }

在 TextField 上使用 navigationBarsWithImePadding() 修饰符

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

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

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

6
投票

使用修饰符

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


3
投票

我也遇到了同样的问题。

使用

OnGlobalLayoutListener
将观察实际的 IME 矩形大小,并将在软键盘完全可见时触发。

对我有用的解决方案:

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),
    ...
)

原产地在这里


2
投票

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

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

我的帖子链接如下:

(撰写 UI)- 键盘(IME)与应用程序的内容重叠


2
投票

就我而言,只需将

android:windowSoftInputMode="adjustResize" 
添加到活动中就足以解决问题。
这取决于您如何构建 UI。如果您的屏幕根目录是可垂直滚动的容器或 Box,则可能会自动管理键盘大小调整。


0
投票

如果您希望文本字段在键盘出现时向上滚动。 以下内容对我有用。 你需要添加这些

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

并将其添加到您的 app/build.gradle

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

0
投票

在我的边缘到边缘应用程序中,我只使用屏幕底部的

Spacer(8.dp + Modifier.height(WindowInsets.safeDrawing.asPaddingValues().calculateBottomPadding()))
。它为导航栏或键盘(如果打开)添加填充,以确保底部元素不会重叠。

它也应该适用于非边缘到边缘的应用程序。


0
投票

window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

   is Deprecated now in compose use below way for make screen resizable on keyboard Open.

首先在清单中添加以下代码(如果有更多活动,请添加所有活动)

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

现在在您想要调整大小的屏幕视图中添加下面

Column(modifier = Modifier.imePadding()){
}

您可以使用 Box、Row 等代替列。

© www.soinside.com 2019 - 2024. All rights reserved.