Jetpack Compose数据加载与重组异常问题咨询
问题:Jetpack Compose中列表重复添加元素与无限重组问题
我通过JSON资产文件加载数据并转为List:
fun onGeneral(context: Context): List<List<General>> { try { val json = context.assets.open("general.json").bufferedReader().use { it.readText() } val list = Gson().fromJson<List<General>>(json, object : TypeToken<List<General>>() {}.type) return listOf( list.subList(0, 30), list.subList(30, 60), list.subList(60, 90), list.subList(90, 120), list.subList(120, 150), list.subList(150, 180), list.subList(180, 210), list.subList(210, 240), list.subList(240, 270), list.subList(270, 300) ) } catch (e: Exception) { return emptyList() } }
因数据量较大,我将其拆分为多个子列表,之后在Compose屏幕中获取第一个子列表:
var items = remember { mutableStateListOf<Item>() } val context = LocalContext.current val general = onGeneral(context)[0] // 第一个子列表
接着把general中的元素添加到items:
general.forEach { items.add(Item(it)) }
同时在屏幕上显示计数器:
Text("Item ${position + 1} of ${items.size}")
问题现象
进入屏幕后,预期文本显示Item 1 of 30,但实际计数器持续递增,且我添加的日志Log.wtf("TST_Output", "Say Hello, when screen entered!")会无限输出。排查发现general.forEach { items.add(Item(it)) }循环在重复执行,理论上循环完成后不该再次触发。
可行解决方法
修改代码后问题消失:
var items: MutableList<Item> = remember { mutableStateListOf() } val temp = arrayListOf<Item>() general.forEach { temp.add(Item(it)) } items = temp
将items声明为MutableList<Item>后,循环不再重复执行。另外我在另一个未加载数据的屏幕中添加了相同日志,本该只触发一次,却触发了三次。
疑问
Jetpack Compose为什么会出现这种异常表现?是不是我的操作存在错误?
附完整屏幕代码:
@Composable @Preview(showBackground = true) @OptIn(ExperimentalPagerApi::class) @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) fun GeneralScreen(controller: NavController = rememberNavController()) { val context = LocalContext.current var items: MutableList<Item> = remember { mutableStateListOf() } var list by remember { mutableStateOf(1) } var position by remember { mutableStateOf(0) } val general = onGeneral(context)[0] val temp = arrayListOf<Item>() general.forEach { temp.add(Item(it)) } items = temp Log.wtf("TST_Output", "Say Hello, when screen entered!") Column(Modifier.fillMaxWidth().padding(10.dp), Arrangement.spacedBy(8.dp), Alignment.CenterHorizontally) { Text("General list $list", fontSize = 18.sp) Text("Item ${position + 1} of ${items.size}", fontSize = 16.sp, color = Color.Gray) } }
内容的提问来源于stack exchange,提问作者Mark Delphi
相关产品推荐
相关产品推荐

