软件键盘与 Jetpack Compose 视图的内容重叠
Software keyboard overlaps content of jetpack compose view
假设我有一些 activity 带有 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")
}
}
}
}
}
如果我启动此 activity 并专注于 TextField,则会弹出一个软件键盘。
但是,界面不会对此做出反应。 ScrollableColumn 的底部边框 (.border(4.dp, Color.Red)
) 以及第 100 个项目 (Text("Item #$i")
) 将不可见。
换句话说,软键盘与内容重叠。
如何让 Jetpack Compose 尊重可见区域的变化(由于软件键盘)?
您可以使用标准 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?
您可以使用 Accompanist 的插入库 https://google.github.io/accompanist/insets
首先在您的可组合层次结构的根部使用 ProvideWindowInsets,大部分时间在您的应用程序主题下方撰写并设置 windowInsetsAnimationsEnabled 真
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
// content }
在 TextField 上使用 navigationBarsWithImePadding() 修饰符
OutlinedTextField(
// other params,
modifier = Modifier.navigationBarsWithImePadding() )
最后确保从 activity(在 onCreate).如果您希望软件键盘 on/off 设置动画,请在 AndroidManifests 中设置您的 activity 的 windowSoftInputMode adjustResize
<activity
android:name=".MyActivity"
android:windowSoftInputMode="adjustResize">
我想到了使用伴奏插入库的想法。
有人可能会感兴趣,因为我的方法不会修改 应用程序的内容。
我link我的post如下:
我遇到了同样的问题。
使用OnGlobalLayoutListener
,它将观察实际的输入法矩形大小,并在软键盘完全可见时触发。
对我有效的解决方案:
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),
...
)
如果您希望 TextField 在出现键盘时向上滚动。
以下它对我有用。
你需要添加这些
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"
假设我有一些 activity 带有 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")
}
}
}
}
}
如果我启动此 activity 并专注于 TextField,则会弹出一个软件键盘。
但是,界面不会对此做出反应。 ScrollableColumn 的底部边框 (.border(4.dp, Color.Red)
) 以及第 100 个项目 (Text("Item #$i")
) 将不可见。
换句话说,软键盘与内容重叠。
如何让 Jetpack Compose 尊重可见区域的变化(由于软件键盘)?
您可以使用标准 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?
您可以使用 Accompanist 的插入库 https://google.github.io/accompanist/insets
首先在您的可组合层次结构的根部使用 ProvideWindowInsets,大部分时间在您的应用程序主题下方撰写并设置 windowInsetsAnimationsEnabled 真
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
// content }
在 TextField 上使用 navigationBarsWithImePadding() 修饰符
OutlinedTextField(
// other params,
modifier = Modifier.navigationBarsWithImePadding() )
最后确保从 activity(在 onCreate).如果您希望软件键盘 on/off 设置动画,请在 AndroidManifests 中设置您的 activity 的 windowSoftInputMode adjustResize
<activity
android:name=".MyActivity"
android:windowSoftInputMode="adjustResize">
我想到了使用伴奏插入库的想法。
有人可能会感兴趣,因为我的方法不会修改 应用程序的内容。
我link我的post如下:
我遇到了同样的问题。
使用OnGlobalLayoutListener
,它将观察实际的输入法矩形大小,并在软键盘完全可见时触发。
对我有效的解决方案:
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),
...
)
如果您希望 TextField 在出现键盘时向上滚动。 以下它对我有用。 你需要添加这些
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"