当前位置: 首页 > 知识库问答 >
问题:

更新Jetpack撰写中的Android视图状态

李烨
2023-03-14

今天早上在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())都不会更新屏幕。日志显示状态得到更新,但关键是每个按钮只更新一次。例如,我有一个收藏夹按钮。单击一次只会推送一次状态更新,任何后续的单击都不会传播。此外,视图本身不会更新。就好像从来没有点击过一样。

现在更改<code>AndroidView的块。更新以使用,并将其强制转换为具体视图类型,效果与预期一致。所有单击都会正确传播,并且卡视图会更新以反映状态。

@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

似乎强制转换到< code>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)
                }
            }
        }
    }

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

共有1个答案

华星驰
2023-03-14

这里的答案是我缺少key值,该值是LazyCol列项所必需的,以便撰写知道哪个项已更改并调用更新。

 类似资料:
  • 如何在JetPack Compose BottomSheet状态更改上实现回调/侦听器机制? 类似的东西: 正如我们过去在Java/静态编程语言中所做的那样。 现在,我正在将其作为lambda传递给另一个需要关闭底片的可组合。 但是我想得到一个回调,底部的工作表已经完全折叠,我可以继续我的任务。 我面临的实际问题:我正在通过按钮单击将可组合文件转换为位图。按钮在BottomSheet内部,需要转换

  • 这是我的导航主机 我从主屏幕到“开始”屏幕很幼稚,但没有从“开始”导航到“计时器”屏幕,我已经传递了与从主屏幕获得的相同的ID。 这个主要可组合的 开始屏幕 当我点击按钮时,应用程序崩溃,错误如下

  • 正如你所看到的,这就是我用MaterialBottomNavigation实现NavHost的方式,我在消息和提要屏幕上都有很多项目,当我在它们两个屏幕之间导航时,它们会自动重构,但我不想这样做,因为那里有很多数据,它在导航时闪烁和fps下降到10以下,我试图在NavHost之前初始化数据viewModels,但结果仍然相同, 有没有办法一次组成屏幕,并在viewModels数据更新时更新它们?

  • Jetpack作曲发布版本: 1.0.0-alpha06 Android Studio Build: 4.2 1Canery 15 我的活动 以上运行时编译此错误: 我的一些gradle设置 def jetpack_compose=“1.0.0-alpha06” 顶级构建脚本

  • 我正在尝试创建一个底部有隐藏按钮的项目列表。默认情况下,按钮在屏幕上不可见。 如果用户滚动到列表底部,则该按钮应显示为列表的最后一项。 我创作了插图来更好地形象化期望的行为: 草图1:包含几个项目的列表 草图2:有很多项目的列表 我已经尝试了类似问题的解决方案(https://stackoverflow.com/a/69196765/11720296),并添加了额外的偏移量,但不幸的是它不起作用。

  • 我在一个应用程序上使用jetpack comuse实现了登录、注册。我将登录用户重定向到主屏幕,并让新用户保持在登录屏幕上。但问题是当我将用户从登录屏幕重定向到主屏幕,用户按下返回按钮时,登录屏幕就会出现。现在我知道这是导航组件的正常行为,但我需要更改它。我如何做到这一点? 使用此行从登录屏幕导航到主屏幕