简体   繁体   中英

Jetpack Compose LazyList - possible to zoom the center item?

I am wondering if it is possible to have a list where you can scroll through - and all the items have a simple view which is shown by default and then a more detailed view which is shown when the item has a specific position on the screen eg. in the center.

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

possible to zoom the center item?

Solution

Detect center item position using LazyListState

Try as below

@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
    }
}

I don't know if understood your question...

If you want to do some action in according with the item position and scroll, you can use the firstVisibleItemIndex and layoutInfo.visibleItemsInfo . The sample below will display the item located at the center with a bigger padding...:

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)
        }
    }
}

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM