避免在jetpack compose中的嵌套列中进行重组

2023-11-30

我正在 jetpack compose 中的嵌套列上工作。我有一个列表,其中包含来自服务器的大量数据。我在布局检查器中进行了检查,我发现每当我的项目添加到列表中时,它都会重新组合并增加计数。所以我的疑问是,如果我在列表中一一添加 100 个项目,那么我的Nested Column100 times recompose?如果没有,有人可以帮我吗?

ListViewComposableActivity.kt

class ListViewComposableActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AppBarScaffold(
                displayHomeAsUpEnabled = true,
                titleId = R.string.activity
            ) {
                ListViewItemStateful()
            }
        }
    }
}

ListView 项目有状态

@Composable
fun ListViewItemStateful(
    viewModel: ListViewModel = koinViewModel(),
) {
    ItemViewListStateless(
        uiState = viewModel.uiState,
        isEnable = viewModel.isEnable,
        scanDeviceList = viewModel.scanResultList,
    )
}

ItemViewList无状态

@Composable
fun ItemViewListStateless(
    uiState: State,
    isEnable: Boolean,
    scanDeviceList: SnapshotStateList<ScanResults>,
) {
    when (uiState) {
        INITIAL,
        FIRST -> {
            ListContent(isEnable, scanDeviceList)
        }
    }
}

列表内容

@Composable
fun ListContent(isEnable: Boolean, scanDeviceList: SnapshotStateList<ScanResults>) {
    AnimatedVisibility(true) {
        Column(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxSize()
                .verticalScroll(rememberScrollState()),
        ) {
            if (isEnable) {
                Column(horizontalAlignment = Alignment.CenterHorizontally) {
                    DeviceList(
                        scanDeviceList,
                        modifier = Modifier.align(Alignment.Start),
                    )
                }
            }
        }
    }
}

设备列表

@Composable
fun ColumnScope.DeviceList(
    scanDeviceList: SnapshotStateList<ScanResults>,
    modifier: Modifier = Modifier,
) {
    Spacer(modifier = Modifier.height(32.dp))
    AnimatedVisibility(
        scanDeviceList.isNotEmpty(),
        modifier = modifier
    ) {
        Column {
            Text(text = "Device List")
            scanDeviceList.forEachIndexed { index, scanResults ->
                Text(text = scanResults.device.name)
            }
        }
    }
}

ListViewModel.kt

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.viewModelScope
import com.abc.app.common.BaseViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class ListViewModel : BaseViewModel() {

    val scanResultList by lazy { mutableStateListOf<ScanResults>() }
    var isEnable by mutableStateOf(false)
        private set
    var uiState by mutableStateOf<State>(State.INITIAL)
        private set

    init {
        viewModelScope.launch {
            (0..10).forEach {
                delay(2000)
                scanResultList.add(ScanResults(Device("item $it")))
            }
        }
        isEnable = true
        uiState = State.FIRST
    }
}


data class ScanResults(val device: Device)
data class Device(val name: String)
enum class State {
    INITIAL,
    FIRST
}

我在列表中添加了一些项目以在布局检查器中显示

enter image description here

在上图中你可以看到DeviceList是重构10次。

我签到了Jetpack Compose:调试重组大约 6:40 分钟,他尝试解决重组问题,并且跳过的重组计数很明显。那么为什么它在重组和跳过部分中显示我的组件树中的计数呢?非常感谢

UPDATE

当我改为@Thracian 回答时,它仍然重新组合跳过

enter image description here

@Composable
fun ColumnScope.DeviceList(
    scanDeviceList:()-> SnapshotStateList<ScanResults>,
    modifier: Modifier = Modifier,
) {
    Spacer(modifier = Modifier.height(32.dp))
    AnimatedVisibility(
        scanDeviceList().isNotEmpty(),
        modifier = modifier
    ) {
        Column {
            Text(text = "Device List")
            scanDeviceList().forEachIndexed { index, scanResults ->
                Item(scanResults.device)
            }
        }
    }
}

@Composable
private fun Item(device: Device) {
    Text(
        modifier = Modifier.border(2.dp, getRandomColor()),
        text = device.name
    )
}

fun getRandomColor() =  Color(
    red = Random.nextInt(256),
    green = Random.nextInt(256),
    blue = Random.nextInt(256),
    alpha = 255
)

在您的问题中,当您向 SnapshotStateList 添加新项目时,整个列都会组成,因为由于内联关键字,列不会创建组合范围。如果您创建一个作用域,则当它读取的值发生变化时,该作用域会被重组。您也可以参考这个问题和答案。

Jetpack Compose 智能重组

添加文本读取设备的项目

@Composable
private fun Item(device: Device) {
    Text(
        modifier = Modifier.border(2.dp, getRandomColor()),
        text = device.name
    )
}

随机颜色是我用来在视觉上显示重组的东西

fun getRandomColor() =  Color(
    red = Random.nextInt(256),
    green = Random.nextInt(256),
    blue = Random.nextInt(256),
    alpha = 255
)

您当前的设置

enter image description here

使用创建范围的可组合项。

@Composable
fun ColumnScope.DeviceList(
    scanDeviceList: SnapshotStateList<ScanResults>,
    modifier: Modifier = Modifier,
) {
    Spacer(modifier = Modifier.height(32.dp))
    AnimatedVisibility(
        scanDeviceList.isNotEmpty(),
        modifier = modifier
    ) {
        Column {
            Text(text = "Device List", color = getRandomColor())
            scanDeviceList.forEachIndexed { index, scanResults ->
//                Text(
//                    modifier = Modifier.border(2.dp, getRandomColor()),
//                    text = scanResults.device.name
//                )

                Item(scanResults.device)
            }
        }
    }
}

enter image description here

当您有很多项目时,尤其是它们不适合视口时,您可以使用 LazyColumn 而不是带有 VerticalScroll 的 Column 来将重组量限制为在视口或 LazyColumn 的可见区域上可见的项目数量

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

避免在jetpack compose中的嵌套列中进行重组 的相关文章

  • 从 Eclipse 启动时创建新的 JFrame 时 Java 将关闭。没有抛出异常

    我正在开发一个在 Eclipse 中开发的 Java 项目 直到今天一切都很好 昨天 在完成我的项目之前 我最后一次运行它以检查一切是否正常并且运行正常 但是今天 当我启动该项目并按下 运行 时 我的应用程序就神秘地关闭了 没有崩溃 没有消
  • C++ 中的 golang 风格“延迟”[重复]

    这个问题在这里已经有答案了 我正在阅读有关 go 语言的defer http blog golang org defer panic and recover陈述 它允许您指定函数结束时要执行的操作 例如 如果您有一个文件指针或资源 则只需指
  • Java 8 哈希映射无法正常工作

    自 java 8 以来 我们面临着 HashMap 行为方式的奇怪问题 当HashMap的键实现了Comparable接口 但compareTo的实现与equals不一致时 HashMaps 长得比它们应该长的大得多 它们包含多个相同元素的
  • 当我在对象上调用函数时,为什么会在非对象上出现此函数调用错误? [复制]

    这个问题在这里已经有答案了 Error 致命错误 调用成员函数 中的非对象上的bind param var www web55 web pdftest events php 76号线 Code public function countDa
  • React Native - 图像缓存

    我阅读了该站点中有关 React Native 图像组件的文档并得到了一些问题 https facebook github io react native docs image html https facebook github io r
  • 如何更新 AngularJS 中的元标记?

    我正在使用 AngularJS 开发一个应用程序 我想更新路线更改的元标记 如何更新 AngularJS 中可以在页面上的 查看源代码 中显示的元标记 这是一段 HTML 代码
  • JQuery 循环遍历动态元素并获取数据值

    我正在尝试使用可折叠面板来完成我的要求 sport on click function var thisId this attr id var thisChildren this sportlist thisChildren each fu
  • Android 上方向改变时如何避免重新启动 Activity

    我正在创建一个 Android 应用程序 在其中在画布上绘制视图 当设备的方向改变时 活动将重新启动 我不想这样 如何避免在方向改变时重新启动 Activity 有多种方法可以做到这一点 但正如给定的here https stackover
  • 是否可以暂时禁用 Postgres 中的索引?

    我在一张表上有一个索引 我想暂时禁用它 但我找不到任何表明这是可能的文档 原因 我有一个索引 它可能会导致与它旨在加速的任何查询无关的查询问题 这是一个新的索引 自从引入以来 整个系统似乎速度较慢 我只是希望能够可靠地消除它作为罪魁祸首 这
  • 如何通过JQuery从不带扩展名的URL中获取页面名称

    我有一个网址 http www example com keyword category php or http www example com keyword category php 4 我需要一个神奇的咒语 它只给我页面名称categ
  • 如何水平和垂直对齐内联块

    什么是最好 最干净的使用CSS对齐 dates div位于标题的右侧 垂直于中间 I tried float right 但这不允许vertical align 我想避免使用浮动 所以我使用inline block 并使用相对定位 有没有更
  • 将用户控件绑定到 bool 属性的相反值

    非常简单 我想做同样的事情this https stackoverflow com questions 534575 how do i invert booleantovisibilityconverter但在winforms中 谷歌似乎提
  • 如何防止外部 CSS 添加和覆盖 ReactJS 组件样式

    我有一个自定义的 ReactJS 组件 我想以某种方式设置样式 并将其作为插件提供给许多不同的网站 但是 当网站使用全局样式 Twitter bootstrap 或其他 css 框架 时 它会添加并覆盖我的组件的样式 例如 全局 css l
  • 针对字段的 Elasticsearch 匹配列表

    我有一个列表 数组或任何你熟悉的语言 例如 姓名 John Bas Peter 我想查询name字段 如果它与这些名称之一匹配 一种方法是使用 OR 过滤器 例如 filtered query match all filter or ter
  • OSX 的网络连接 NSNotification?

    我只需要在分配有效 IP 地址时发出通知即可 我尝试过通过 SCreachability 进行轮询 但这似乎效率低下 有什么建议么 这看起来应该很简单 但我已经努力了几个小时才能让任何东西发挥作用 我知道这有点旧 但所选的答案并不理想 SC
  • 如何将 JSLint 用于依赖于 JQuery 的代码段?

    我对 Javascript 比较陌生 我想通过 JSLint 运行我周末玩的那段代码 这样它就可以指出我在哪里是个十足的白痴 不幸的是 我收到了大量关于缺少函数声明的错误 这些函数声明是 JQuery javascript 库及其各种插件的
  • 定义应保存 user.config 文件的自定义路径?

    如果我重命名我编译的应用程序 例如myapp exe to app exe然后 当我运行重命名的可执行文件时 会在此路径中生成新的用户设置文件夹 C Users User AppData Local CompanyName Executab
  • 使用 CRTP 模式时继承中的不明确方法

    我正在定义一个DoubleWrapper类继承自两个 CRTP 基类 Ratioable and Divable 两者都定义operator 具有不同的签名 T operator double const scalar const retu
  • 如何使相对div居中?

    我一直在尝试让以下代码工作几个小时 但没有成功 您能帮我将项目 div 居中吗 即使页面放大和缩小时 这是我的 HTML 和 CSS bottom position absolute top 100 left 0 right 0 backg
  • 将多个ggplot2图保存为列表中的R对象并在网格中重新显示

    我想在大型 for 循环期间将多个绘图 使用 ggplot2 保存到列表中 然后随后在网格中显示图像 使用 grid arrange 我已经尝试了两种解决方案 1 将其存储在列表中 如下所示 pltlist qplot lt qplot 然

随机推荐

  • 删除 woocommerce 简短描述字段

    我正在创建一个专门为 woocommerce 使用而设计的主题 该主题的设计未使用 产品简短描述 使用以下命令可以轻松地删除页面上显示的描述 remove action woocommerce single product summary
  • ajax如何从PHP文件返回错误消息

    当我将鼠标悬停在任何单词上时 总是会显示一个黑框 如果 PHP 代码返回文本 它将显示在黑框中 它应该如此 但是 如果未返回文本 我希望它返回一个错误函数 这样我就可以稍后更改黑框的 CSS 使其宽度为0px代替400px var x th
  • Rails 4 CSV 导入并将值设置为键值

    我是一名完全的 Rails n00b 我确信这是一件很容易做到的事情 但我遇到了麻烦 当我从 csv 导入该记录时 我想获取 URL 中键的值并将其设置为数据库中记录的 category id 我可以通过在 csv 文件中创建 Catego
  • C随机主元快速排序(改进配分函数)

    我是一名计算机科学专业的学生 刚刚开始 我正在努力从伪代码编写快速排序的随机枢轴版本 我已经编写并测试了它 但一切都很完美 分区部分看起来有点太复杂了 感觉漏掉了什么或者想太多了 我不明白这是否可以 或者我是否犯了一些可以避免的错误 长话短
  • 自定义元素上的 QuerySelector

    我想选择 id home i 的图标并给出点击效果 但是 当我使用document querySelector left navbar nav 它返回为null 我正在使用一个基本的 javascript 自定义元素 这似乎是导致问题的原因
  • 分钟和秒正则表达式

    我正在尝试验证分钟 秒输入 其中分钟可以是 07 或 7 我可以使用下面的方法验证 07 35 但不能验证 7 35 当我处理输入时 如果值小于 9 我可以附加零 但也希望能够让用户输入 7 35 0 5 d 0 5 d 您可以将第一个数字
  • wglext - 扩展未安装在 OpenGL 上下文中

    我正在尝试使用 wglSwapIntervalEXT int Interval 在 OpenGl 中使用 WGL EXT swap control 禁用垂直同步 我试图包含 wglext 标头 但经过多次搜索后 它似乎没有安装在我的电脑上
  • tensorflow retrain.py app.run() 得到意外的关键字参数“argv”

    我正在尝试运行 Tensorflow for Poets 示例 我通过以下内容 python examples image retraining retrain py bottlenext dir tf files bottlenecks
  • 删除 C 中输出末尾的空格

    以下代码用于按螺旋顺序打印矩阵的元素 该程序运行良好 然而 问题是我检查程序的在线编译器不接受输出末尾的尾随空格 谁能给我一些关于如何绕过输出中添加的最后一个空格的想法 作为参考 我的代码如下 是的 变量名称很糟糕 我正在努力改变放置随机变
  • MySql“选择位置”和 C#

    如何从 SelectWhere 语句中读取返回值 每次运行时标签中都没有返回值 也没有语法错误 command CommandText select product price from product where product name
  • 禁用错误的打字稿错误

    我已经使用 jspm 安装了 interact js 以及 npm 以便打字稿满意 该应用程序运行良好 但我的代码显示错误 import interact from interact js interact gt typescript er
  • Android计算Horizo​​ntalScrollView中的scrollTo位置

    我有 Horizo ntalScrollView 和几个 TextView 每个 TextView 可能包含不同长度的文本 我应该如何计算使用 scrollTo x y 滚动到的正确偏移量 滚动有效 但与预期不同 我已经尝试了各种方法 每个
  • 翻译我的主题的 function.php 文件中的自定义标签字段

    在社区的帮助下 我成功创建 保存标签及其值并将其打印到单个产品页面 我还可以使用将输入值翻译成不同的语言Polylang 但是翻译自定义标签 条件和品牌 非常困难 有人可以帮助我解决这些问题吗 我尝试使用Polylang Saywhat 没
  • 用php动态创建zip

    使用 php 创建动态 zip 文件的最简单方法是什么 例如 我在服务器上有这些文件 Root gt Folder 1 gt file1 wav Root gt Folder 2 gt file2 jpg 我想创建一个包含这两个文件的 zi
  • +Android Webview - 如何自动滚动页面?

    我想在网络视图中打开一个html页面 并使其根据通过计时器设置的时间间隔自动向下滚动 虽然下面的示例适用于桌面 但此链接应该让您了解我想要实现的目标 在页面的右上方启用自动滚动 example 首先 我考虑打开一个网页 然后使用某种可以模拟
  • Sed/Awk 删除第二次出现的字符串 - 平台无关

    我正在 bash 中寻找一行既适用于 linux 又适用于 OS X 的行 以删除包含所需字符串的第二行 Header 1 2 Header 10 11 应该成为 Header 1 2 10 11 我的第一次尝试是使用 sed 的删除选项
  • 如何在 Google 地图中设计高尔夫球场(沙丘和果岭)?

    我目前正在使用时髦的地图超轻主题设计我的 Google 地图 人们所期望的造型 景观 影响高尔夫球场 featureType landscape elementType geometry stylers color f5f5f5 light
  • 如何在Azure Blob上实现快速搜索?

    我已完成编写将文件 文本文件 上传到 azure blob 存储的代码 现在我想提供基于文本文件内容的搜索 对于前 如果我搜索 Hello 那么包含 Hello 单词的文件名应该出现在搜索结果中 这是我要搜索的代码 class BlobSe
  • Javascript 到 csv 导出编码问题

    我需要将 javascript 数组导出到 Excel 文件并下载它 我正在这段代码中执行此操作 data 是一个 JavaScript 对象数组 var csvContent data text csv charset utf 8 dat
  • 避免在jetpack compose中的嵌套列中进行重组

    我正在 jetpack compose 中的嵌套列上工作 我有一个列表 其中包含来自服务器的大量数据 我在布局检查器中进行了检查 我发现每当我的项目添加到列表中时 它都会重新组合并增加计数 所以我的疑问是 如果我在列表中一一添加 100 个