假设我有一些与喷气背包撰写内容相关的活动
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 尊重可见区域的变化(由于软件键盘)?
除了 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>
Modifier.imePadding()
来对 IME 可见性做出反应
Box(Modifier.imePadding()) {
// content
}
您可以使用标准的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 */ }
}
}
否则,您可以使用清单中的标志。浏览此处获取更多信息: 显示软键盘时向上移动布局?
您可以使用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">
使用修饰符
imePadding()
。这将允许特定的组合在键盘弹出时自行调整。这不需要您在活动上设置任何标志
我也遇到了同样的问题。
使用
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),
...
)
就我而言,只需将
android:windowSoftInputMode="adjustResize"
添加到活动中就足以解决问题。如果您希望文本字段在键盘出现时向上滚动。 以下内容对我有用。 你需要添加这些
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"
在我的边缘到边缘应用程序中,我只使用屏幕底部的
Spacer(8.dp + Modifier.height(WindowInsets.safeDrawing.asPaddingValues().calculateBottomPadding()))
。它为导航栏或键盘(如果打开)添加填充,以确保底部元素不会重叠。
它也应该适用于非边缘到边缘的应用程序。
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 等代替列。