我有一个列表,其中每个项目都包含一个带有四个输入字段的表单,当我单击输入字段时,键盘会打开并且输入字段重叠。您以前遇到过这个问题吗?
预期行为:输入字段移至键盘上方。
这就是我的屏幕在视觉上的样子
这就是代码中的样子:
setContent {
ConsumerTheme {
val listState = rememberLazyListState()
val scrollState = rememberScrollState()
val scaffoldState = rememberScaffoldState()
Scaffold(
scaffoldState = scaffoldState,
backgroundColor = MaterialTheme.colors.background,
topBar = {
Toolbar()
},
) { innerPadding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
) {
listState.firstVisibleItemIndex
LazyColumn(
modifier = Modifier
.weight(1f)
.scrollable(scrollState, Orientation.Vertical),
state = listState
) {
item {
SetupListRowStepper()
}
item {
// Divider wit label
DividerWithLabel(LocalContext.current.getString(R.string.you))
}
item {
// list row avatar (Client)
ClientProfile()
}
// Guest list
item {
SetupGuestList()
}
}
NextCustomButton(
formState = groupBookingViewModel.guestState.value.areAllValidationFieldsValid,
processPreBookingAttempt = groupBookingViewModel::processPreBookingAttempt,
saveGroupTelemetry = ::saveGroupTelemetry
)
}
}
}
}
我的
SetupGuestList()
也是一个列表:
Column {
repeat(numOfGuests) {
GuestFormItem(
it,
clientGuest,
inputFieldsValidation
)
}
}
这是在输入字段聚焦/编辑后打开键盘时屏幕的外观:
在使用 LazyColumn 和 listState 尝试不同的操作以滚动到列表中的特定项目后,我决定保留它,而是使用带有垂直滚动的 Column ,因为我没有让它正常工作。
这就是我的可滚动容器现在的样子,它取代了 LazyColumn
Column(
modifier = Modifier
.weight(1f)
.verticalScroll(scrollState)
) {
SetupListRowStepper()
// Divider wit label
DividerWithLabel(LocalContext.current.getString(R.string.you))
// list row avatar (Client)
ClientProfile()
SetupGuestList(
coroutineScope,
scrollState
)
}
现在我们必须在输入字段获得焦点时执行手动滚动。 为此,我们必须与 CoroutineScope 和 ScrollState 进行交互。
在包装 inpun 字段的项目中,获取项目在根“布局”中的位置,如下所示:
var scrollToPosition by remember { mutableStateOf(0F) }
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.onGloballyPositioned { layoutCoordinates ->
scrollToPosition = scrollState.value + layoutCoordinates.positionInRoot().y
}
) {
现在,当输入字段聚焦在卡片项目中时,您必须像这样执行滚动:
coroutineScope.launch {
// wait until the keyboard is open
delay(100)
scrollState.animateScrollTo(
scrollToPosition.roundToInt()
)
}
您可以尝试使用 scrollToPosition 的值,考虑输入字段位置的偏移量,...
目前 Compose 存在焦点问题,只有一个混乱的解决方法:
val relocation = remember { BringIntoViewRequester() }
val scope = rememberCoroutineScope()
OutlinedTextField(
value = text,
modifier = Modifier.bringIntoViewRequester(relocation)
.onFocusEvent {
if (it.isFocused) scope.launch { delay(300); relocation.bringIntoView() }
},
onValueChange = ...,
label = ...,
)
您需要为每个字段执行此操作,获得焦点后该字段必须位于键盘上方。
issuestracker 上的相关问题:issue #1、issue #2
对于仍然遇到同样问题的人:
我只需应用即可解决 IME 布局问题
Modifier.imePadding()
任何您需要的地方。就我而言,我使用了可滚动的 Column() 并在屏幕底部有粘性按钮。将 imePadding() 应用于列和按钮会导致每当键盘可见时两个视图都会向上滚动。