Я использую ScalingLazyColumn с очень длинным текстом внутри следующим образом:
@Preview(device = Devices.WEAR_OS_SMALL_ROUND, showSystemUi = true)
@Composable
fun Test(modifier: Modifier = Modifier) {
val scalingLazyState = remember { ScalingLazyListState() }
val focusRequester = remember { FocusRequester() }
Scaffold(
modifier = modifier,
positionIndicator = { PositionIndicator(scalingLazyListState = scalingLazyState) }
) {
ScalingLazyColumn(
modifier = Modifier.scrollableColumn(focusRequester, scalingLazyState),
state = scalingLazyState,
) {
item {
Text(
longText,
Modifier
.padding(top = 20.dp, start = 16.dp, end = 16.dp, bottom = 48.dp),
textAlign = TextAlign.Center,
)
}
}
}
}
val longText =
"Take the plunge\n" +
"\n" +
"commit oneself to a course of action about which one is nervous.\n" +
"\n" +
"\"she wondered whether to enter for the race, but decided to take the plunge\"\n" +
"\"They're finally taking the plunge and getting married.\"\n" +
"\n" +
"\n" +
"plunge:\n" +
"jump or dive quickly and energetically.\n" +
"\"our daughters whooped as they plunged into the sea\"\n"
Но по какой-то причине, когда я запускаю приложение, фокус переходит на конец текста, а не на начало, что выглядит как ошибка. Я пытался играть с различными параметрами ScalingLazyColumn (anchorType, autoCentering, scalingParams) безрезультатно.
Любая идея, как это исправить и заставить ScalingLazyColumn фокусироваться на начале первого элемента при запуске приложения?
ScalingLazyListState по умолчанию находится в центре второго элемента (индекс 1). Вместо этого вы можете указать ему начинать с первого элемента, и даже в параметрах ScalingLazyColumn использовать начало элементов.
val scalingLazyState = remember { ScalingLazyListState(initialCenterItemIndex = 0) }
val focusRequester = remember { FocusRequester() }
Scaffold(
modifier = Modifier,
positionIndicator = { PositionIndicator(scalingLazyListState = scalingLazyState) }
) {
ScalingLazyColumn(
modifier = Modifier.scrollableColumn(focusRequester, scalingLazyState),
state = scalingLazyState,
anchorType = ScalingLazyListAnchorType.ItemStart
) {
item {
Text(
longText,
Modifier
.padding(top = 20.dp, start = 16.dp, end = 16.dp, bottom = 48.dp),
textAlign = TextAlign.Center,
)
}
}
}
ах, я вижу, вы прикрепили фрагмент кода. Да, это работает, но при этом он слишком сильно прыгает вверх, где у вас первая верхняя половина экрана пуста, а нижняя половина экрана начинается с первого элемента.
Версия Джона Никола исправляет это, добавляя смещения.
После нескольких часов разочарования я наконец нашел решение. Если вы читаете документацию для ScalingLazyColumn, там написано:
«Если разработчику нужен собственный контроль над положением и расстоянием, он можно отключить автоцентрирование и предоставить contentPadding».
Так что все, что вам нужно сделать, это просто добавить autoCentering = null в ScalingLazyColumn.
Это рабочий код, в котором фокус будет находиться в начале текста:
val scalingLazyState = remember { ScalingLazyListState() }
val focusRequester = remember { FocusRequester() }
Scaffold(
modifier = modifier,
positionIndicator = { PositionIndicator(scalingLazyListState = scalingLazyState) }
) {
ScalingLazyColumn(
modifier = Modifier.scrollableColumn(focusRequester, scalingLazyState),
state = scalingLazyState,
autoCentering = null,
) {
item {
Text(
longText,
Modifier
.padding(top = 20.dp, start = 16.dp, end = 16.dp, bottom = 48.dp),
textAlign = TextAlign.Center,
)
}
}
}
ContentPadding, о котором он говорит, является параметром ScalingLazyColumn. ``` public fun ScalingLazyColumn( модификатор: Модификатор = Модификатор, состояние: ScalingLazyListState = запомнитьScalingLazyListState(), contentPadding: PaddingValues = PaddingValues(horizontal = 10.dp), ```
Это тестовое задание позволит вам поиграть со всеми параметрами, чтобы увидеть начальную позицию.
Отключение автоцентрирования — это вариант, но я бы старался избегать его в большинстве случаев, так как это усложнит обработку правильного заполнения на устройствах разных размеров и часто приводит к возможности прокручивать элементы списка либо в начале, либо конец.
Я не совсем уверен, чего вы хотите достичь, когда говорите, что хотите, чтобы фокус был на начале первого элемента, но следующее должно дать вам то, что вам нужно.
ScalingLazyListAnchorType.ItemStart
initialCenterItemScrollOffset
, чтобы немного сдвинуть начало вашего элемента.@Preview(device = Devices.WEAR_OS_SMALL_ROUND, showSystemUi = true)
@Composable
fun SingleItemSLCWithLongText(modifier: Modifier = Modifier) {
val scalingLazyState = remember { ScalingLazyListState(initialCenterItemIndex = 0, initialCenterItemScrollOffset = 80) }
val focusRequester = remember { FocusRequester() }
Scaffold(
modifier = modifier.background(Color.Black),
positionIndicator = { PositionIndicator(scalingLazyListState = scalingLazyState) }
) {
ScalingLazyColumn(
modifier = Modifier.scrollableColumn(focusRequester, scalingLazyState),
autoCentering = AutoCenteringParams(itemIndex = 0, itemOffset = 80),
state = scalingLazyState,
anchorType = ScalingLazyListAnchorType.ItemStart
) {
item {
Text(
longText,
Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 48.dp),
textAlign = TextAlign.Center,
)
}
}
}
}
Вот скриншот того, как изначально выглядит экран
Пробовал так, не получилось