【问题标题】:Updating AndroidView state in Jetpack Compose在 Jetpack Compose 中更新 AndroidView 状态
【发布时间】:2021-03-09 11:21:00
【问题描述】:

今天早上遇到了一个关于 AndroidView 的奇怪情况。

我有一个如下所示的 ProductCard 界面

interface ProductCard {
    val view: View
    fun setup(
        productState: ProductState,
        interactionListener: ProductCardView.InteractionListener
    )
}

这个接口可以由多个视图实现。

呈现AndroidView 列表的可组合组件使用ProductCard 获取视图并在重组发生时传递状态更新。

@Composable
fun BasketItemsList(
    modifier: Modifier,
    basketItems: List<ProductState>,
    provider: ProductCard,
    interactionListener: ProductCardView.InteractionListener
) {
    LazyColumn(modifier = modifier) {
        items(basketItems) { product ->
            AndroidView(factory = { provider.view }) {
                Timber.tag("BasketItemsList").v(product.toString())
                provider.setup(product, interactionListener)
            }
        }
    }
}

使用此示例,与 ProductCard 视图(调用 ProductCard.setup())的任何交互都不会更新屏幕。日志显示状态已更新,但问题是每个按钮仅更新一次。例如,我有一个收藏夹按钮。单击它一次只会推送一次状态更新,任何后续单击都不会传播。视图本身也不会更新。就好像它从未被点击过一样。

现在将 AndroidView.update 的块更改为使用 it 并将其转换为具体的视图类型可以按预期工作。所有点击都会正确传播,并且卡片视图会更新以反映状态。

@Composable
fun BasketItemsList(
    modifier: Modifier,
    basketItems: List<ProductState>,
    provider: ProductCard,
    interactionListener: ProductCardView.InteractionListener
) {
    LazyColumn(modifier = modifier) {
        items(basketItems) { product ->
            AndroidView(factory = { provider.view }) {
                Timber.tag("BasketItemsList").v(product.toString())
//                provider.setup(product, interactionListener)
                (it as ProductCardView).setup(product, interactionListener)
            }
        }
    }
}

我在这里缺少什么?为什么使用ProductCard 在将视图转换为其类型时不起作用?


更新 1

似乎投射到 ProductCard 也可以

    @Composable
    fun BasketItemsList(
        modifier: Modifier,
        basketItems: List<ProductState>,
        provider: ProductCard,
        interactionListener: ProductCardView.InteractionListener
    ) {
        LazyColumn(modifier = modifier) {
            items(basketItems) { product ->
                AndroidView(factory = { provider.view }) {
                    Timber.tag("BasketItemsList").v(product.toString())
    //                provider.setup(product, interactionListener)
                    (it as ProductCard).setup(product, interactionListener)
                }
            }
        }
    }

所以问题是为什么我们必须在AndroidView.update 中使用it 而不是对视图的任何其他引用?

【问题讨论】:

    标签: android kotlin android-jetpack-compose


    【解决方案1】:

    这里的答案是我错过了 LazyColumn 项目所需的 key 值,以便 compose 知道哪个项目已更改并对其调用更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 1970-01-01
      相关资源
      最近更新 更多