LazyColumn/LazyRow 如何兼容两个不同的列表?

问题描述 投票:0回答:1

我有一个

Custom Composable Calendar
这里

我尝试添加一个在月视图和周视图之间切换的功能。

代码要点如下:

LazyRow {
    items(
        key = { page -> state.getKey(page) },
    ) { page ->
        monthFiled(
            date = state.getDateByPage(page),
        )
    }
}

重点是:

  1. 在月视图模式下,
    state.getKey(page)
    返回类似
    YearMonth
    的键(或页面或其他)。
  2. 在周模式下,
    state.getKey(page)
    返回喜欢
    year_weeks
    的键(或页面或其他)。

他们是不同的。

为了确保动画正常工作,我希望月视图和周视图之间切换时的按键保持一致。

但是,月视图和周视图之间的关系不是一对一,而是一对多(1:5)。

有什么可以帮助我在月视图和周视图之间切换,以及在月视图和周视图之间平滑地来回切换吗?

这是我的
minimal reproducible example

private interface View {
    val count: Int
    fun key(index: Int): Any
    fun content(index: Int): List<Int>
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MainScreen(innerPadding: PaddingValues) {
    val list = listOf(0, 1, 2, 3, 4, 5)
    // expand
    val view1 = object : View {
        override val count: Int get() = list.size / 3
        override fun key(index: Int) = list[index * 3]
        override fun content(index: Int) = list.subList(index * 3, (index + 1) * 3)
    }
    // collapse
    val view2 = object : View {
        override val count: Int get() = list.size
        override fun key(index: Int) = list[index]
        override fun content(index: Int) = list.subList(index / 3 * 3, (index / 3 + 1) * 3)
    }

    var view: View by remember { mutableStateOf(view1) }

    val state = rememberLazyListState()
    LazyColumn(
        modifier = Modifier
            .height(100.dp)
            .clickable { view = if (view == view1) view2 else view1 },
        state = state,
        flingBehavior = rememberSnapFlingBehavior(state)
    ) {
        items(
            count = view.count,
            key = view::key,
        ) { index ->
            Row(
                modifier = Modifier.fillParentMaxHeight(),
            ) {
                view.content(index).forEach { item ->
                    AnimatedVisibility(visible = view == view1 || view.key(index) == item) {
                        Text(
                            "$item",
                            modifier = Modifier
                                .width(100.dp)
                                .fillMaxHeight()
                                .border(1.dp, Purple80),
                        )
                    }
                }
            }
        }
    }
}

它以两种不同的方式显示列表:view1 和 view2。

  1. 一种方法是每行显示 3 个项目,
  2. 另一种方法是每行显示 1 个项目。

由于密钥重复使用,

element0和element0~2之间可以实现展开和折叠的动画。

但是element1和element0~2之间无法实现动画。

您有什么好的建议吗?

android calendar android-jetpack-compose lazycolumn
1个回答
0
投票

这些键没有帮助,因为您只能将 view1 的键映射到 view2,而不能将 view1 的键映射到 view2。

在切换视图后,忘记按键并使用

LazyListState
requestScrollToItem
来调整滚动位置:

.clickable {
    view = if (view == view1) {
        state.requestScrollToItem(state.firstVisibleItemIndex * 3)
        view2
    } else {
        state.requestScrollToItem(state.firstVisibleItemIndex / 3)
        view1
    }
},

现在切换视图时不再需要

items
'
key
参数。如果您不需要钥匙做其他事情,您可以将它们完全删除。

© www.soinside.com 2019 - 2024. All rights reserved.