![](/img/trans.png)
[英]How to make item appear in the center of the screen Jetpack Compose when using LazyRow or Column?
[英]Jetpack Compose LazyRow - Center selected item
如何計算 LazyRow 中所選項目的 position 並將其用於屏幕上的項目居中? 這些項目將根據其內容具有不同的大小。
如果我使用lazyListState.animateScrollToItem(index)
go,則所選項目將位於 LazyRow 的左側。
我目前擁有的代碼:
@Composable
fun Test() {
Column {
TestRow(listOf("Angola", "Bahrain", "Afghanistan", "Denmark", "Egypt", "El Salvador", "Fiji", "Japan", "Kazakhstan", "Kuwait", "Laos", "Mongolia"))
TestRow(listOf("Angola", "Bahrain", "Afghanistan"))
}
}
@OptIn(ExperimentalSnapperApi::class)
@Composable
fun TestRow(items: List<String>) {
val selectedIndex = remember { mutableStateOf(0) }
val lazyListState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
LazyRow(
modifier = Modifier.fillMaxWidth(),
state = lazyListState,
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
contentPadding = PaddingValues(horizontal = 12.dp),
flingBehavior = rememberSnapperFlingBehavior(
lazyListState = lazyListState,
snapOffsetForItem = SnapOffsets.Start
)
) {
itemsIndexed(items) { index, item ->
TestItem(
content = item,
isSelected = index == selectedIndex.value,
onClick = {
selectedIndex.value = index
coroutineScope.launch {
lazyListState.animateScrollToItem(index)
}
}
)
}
}
}
@Composable
fun TestItem(
content: String,
isSelected: Boolean,
onClick: () -> Unit
) {
Button(
modifier = Modifier.height(40.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = if (isSelected) Color.Green else Color.Yellow,
contentColor = Color.Black
),
elevation = null,
shape = RoundedCornerShape(5.dp),
contentPadding = PaddingValues(0.dp),
onClick = onClick
) {
Text(
modifier = Modifier.padding(horizontal = 16.dp, vertical = 10.dp),
text = (content).uppercase(),
)
}
}
代碼horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)
是為了確保 LazyRow 在沒有足夠的項目滾動時將所有項目居中。 包含 3 個項目的示例:
我已經嘗試過在類似問題上發布的各種建議,但沒有找到解決方案的運氣。 jetpack-compose-lazylist-可能縮放中心項目如何在 lazycolumn-on-jetpackcompose /jetpack-compose-make-the-first-element-in 中聚焦一個不可見的項目-a-lazyrow-be-aligned-to-the-center-o
我找到了適合我需要的解決方案,因為我不希望導航到選定的項目,而看不到它。
此解決方案無法將屏幕上不可見的項目居中。
coroutineScope.launch {
val itemInfo = lazyListState.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
if (itemInfo != null) {
val center = lazyListState.layoutInfo.viewportEndOffset / 2
val childCenter = itemInfo.offset + itemInfo.size / 2
lazyListState.animateScrollBy((childCenter - center).toFloat())
} else {
lazyListState.animateScrollToItem(index)
}
}
希望噸
改進@Markram 的回答
您可以創建“LazyListState”的擴展:
fun LazyListState.animateScrollAndCentralizeItem(index: Int, scope: CoroutineScope) {
val itemInfo = this.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
scope.launch {
if (itemInfo != null) {
val center = this@animateScrollAndCentralizeItem.layoutInfo.viewportEndOffset / 2
val childCenter = itemInfo.offset + itemInfo.size / 2
this@animateScrollAndCentralizeItem.animateScrollBy((childCenter - center).toFloat())
} else {
this@animateScrollAndCentralizeItem.animateScrollToItem(index)
}
}
}
然后直接在您的 Composable 中使用它:
val coroutineScope = rememberCoroutineScope()
coroutineScope.launch {
listState.animateScrollAndCentralizeItem(index , this)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.