【问题标题】:Why won't the recomposition trigger for my LazyColumn为什么我的 LazyColumn 的重组不会触发
【发布时间】:2021-12-01 21:37:17
【问题描述】:

我有一个 LazyColumn,它有多个列表,它应该根据 index 值显示。但是,当我更改 index 时,列表会发生变化,但在我向下滚动并向上滚动之前不会重绘这些项目。 我已经折腾了 remember 关键字,改变了我的逻辑 N 次,它仍然不会更新。 这是我的课

    @Composable
fun MainContent() {
    val state = homeViewModel.state.collectAsState(initial = HomepageState.Loading)
    Theme(config = config) {
        when (state.value) {
            is HomepageState.Loading -> Box(
                modifier = Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ) { CircularProgressIndicator() }
            is HomepageState.Multi -> with(state.value as HomepageState.Multi) {
                updateHomepageImagePreference(index)
                LazyColumnContent(homepage = items, switcher, logo, index)
            }
        }
    }
}

主页[index] 部分是我想触发重组的部分。我尝试传递正确的列表而不是更改索引,但结果是一样的

@Composable
private fun LazyColumnContent(
    homepage: List<List<ModuleConfig>>,
    switcher: HomepageSwitcherTheme?,
    logo: HomepageThemeNavLogo?,
    index: Int = 0
) {
    LaunchedEffect(key1 = index) {
        updateHomepageSwitcher(switcher)
        updateNavigationBarLogo(logo)
    }
    return LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .background(vennConfig.themeConfig.backgroundColor?.color)
    ) {
        itemsIndexed(homepage[index]) { _, item ->
            AndroidView(
                modifier = Modifier.fillMaxSize(),
                factory = {
                    val productsInCategoryCriteriaSatisfied =
                        if (item.requiresProductsInCategoryId.isNullOrEmpty()) true
                        else categoryHasProducts[item.requiresProductsInCategoryId] ?: true

                    return@AndroidView if (productsInCategoryCriteriaSatisfied) moduleFactory.build(
                        item,
                        requireContext()
                    )
                    else View(context) // blank view
                }
            )
        }
    }
}

我猜我在使用 Compose 时做错了什么,但我不知道是什么问题。

【问题讨论】:

    标签: android kotlin android-jetpack-compose


    【解决方案1】:

    AndroidView factory 只会在视图出现后被调用。如果您需要在同一视图上更新item,可以使用update。此外,当您没有可显示的内容时,您无需创建空视图,只需按需创建 AndroidView

    val productsInCategoryCriteriaSatisfied =
        if (item.requiresProductsInCategoryId.isNullOrEmpty()) true
        else categoryHasProducts[item.requiresProductsInCategoryId] ?: true
    
    if (productsInCategoryCriteriaSatisfied) {
        AndroidView(
            modifier = Modifier.fillMaxSize(),
            factory = { context ->
                moduleFactory.build(
                    item,
                    context
                )
            },
            update = {
                it.item = item
            },
        )
    }
    

    另一个问题是您可能更改了商品顺序。

    解决这个问题最简洁的方法是使用key 参数:默认情况下它是相等的项目索引。

    您的项目完美地具有id,但您也可以根据任何其他项目属性构建key。当 key 与上次重组后不同时 - AndroidView 将被重新创建。 p.s.不需要索引的时候,可以用items代替itemsIndexed

    LazyColumn {
        items(list, key = { it.id }) { item ->
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-08
      • 2014-07-01
      • 1970-01-01
      • 2016-01-21
      • 2016-02-10
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-03-19
      相关资源
      最近更新 更多