Jetpack Compose LazyList - 可以缩放中心项目吗?

Jetpack Compose LazyList - possible to zoom the center item?

我想知道是否可以有一个可以滚动浏览的列表 - 所有项目都有一个默认显示的简单视图,然后是一个更详细的视图,当项目具有特定的在屏幕上的位置,例如。在中间。

-------------------------
| + | Item              |
-------------------------
-------------------------
| + | Item              |
-------------------------
-------------------------
| + | Item              |
-------------------------
-------------------------
|+++| Item Title        <
|+++|                   |
|+++| Item desciption   <
-------------------------
-------------------------
| + | Item              |
-------------------------
-------------------------
| + | Item              |
-------------------------
-------------------------
| + | Item              |
-------------------------

possible to zoom the center item?

解决方案

使用 LazyListState

检测中心项目位置

尝试如下

@Composable
fun Example() {
    val lazyState = rememberLazyListState()

    val centerPosition by remember { // caching position for prevent recomposition 
        derivedStateOf {
            val visibleInfo = lazyState.layoutInfo.visibleItemsInfo
            if (visibleInfo.isEmpty()) -1
            else {
                //TODO: enhance calculate logic for specific position
                val offset = (visibleInfo.last().index - visibleInfo.first().index) / 2
                visibleInfo.first().index + offset
            }
        }
    }

    LazyColumn(
        modifier = Modifier.fillMaxSize(),
        state = lazyState
    ) {
        itemsIndexed(/* your items */) { index, item ->
            Child(expanded = index == centerPosition)
        }
    }
}

@Composable
fun Child(
    expanded: Boolean
) {
    if (expanded) {
        //show your expanded layout
    } else {
        //show your collapsed layout
    }
}

不知道有没有看懂你的问题...

如果你想做一些根据项目位置和滚动的动作,你可以使用firstVisibleItemIndexlayoutInfo.visibleItemsInfo。下面的示例将以更大的填充显示位于中心的项目...:[=​​14=]

val state = rememberLazyListState()
val midIndex by remember(state.firstVisibleItemIndex) {
    derivedStateOf {
        state.layoutInfo.visibleItemsInfo.run {
            val firstVisibleIndex = state.firstVisibleItemIndex
            if (isEmpty()) -1 else firstVisibleIndex + (last().index - firstVisibleIndex) / 2
        }
    }
}
LazyColumn(
    state = state
) {
    itemsIndexed(items) { index, item ->
        val bgColor = if (index == midIndex) Color.Gray else Color.Transparent
        val padding = if (index == midIndex) 32.dp else 8.dp
        Box(Modifier
            .fillMaxWidth()
            .background(bgColor, RoundedCornerShape(8.dp))
            .padding(horizontal = 8.dp, vertical = padding)
        ) {
            Text(text = item)
        }
    }
}