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
}
}
不知道有没有看懂你的问题...
如果你想做一些根据项目位置和滚动的动作,你可以使用firstVisibleItemIndex
和layoutInfo.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)
}
}
}
我想知道是否可以有一个可以滚动浏览的列表 - 所有项目都有一个默认显示的简单视图,然后是一个更详细的视图,当项目具有特定的在屏幕上的位置,例如。在中间。
-------------------------
| + | 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
}
}
不知道有没有看懂你的问题...
如果你想做一些根据项目位置和滚动的动作,你可以使用firstVisibleItemIndex
和layoutInfo.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)
}
}
}