Jetpack Compose LazyColumn初始选中项未勾选,滚动后恢复问题求助
问题分析与解决
问题根源
- 初始化时机错位:
selectedTongNumber的初始化逻辑放在LaunchedEffect中,而LaunchedEffect会在Compose重组完成后才执行。你直接在Compose函数内创建的tongNumberList,第一次循环设置tn.isSelected时,selectedTongNumber还未填充数据,导致初始isSelected全为false。 - 状态未联动:
isNumberChecked用remember存储了初始值,但后续selectedTongNumber更新后,这个状态不会自动同步——因为它没有监听数据源变化。只有当列表项被滚动回收再复用,才会重新读取tongNumber.isSelected的最新值,此时勾选状态才显示正常。 - 非可观察列表:
tongNumberList是普通mutableList,修改其isSelected属性不会触发Compose重组,所以即使后续更新了tongNumber.isSelected,UI也不会立刻刷新。
修复后的代码
val selectedTongNumber = remember { mutableStateListOf<String>() } // 用remember包裹列表,避免每次重组重新创建,保留状态 val tongNumberList = remember { mutableListOf( TongNumber("012345"), TongNumber("014567"), TongNumber("024568"), TongNumber("034589"), TongNumber("124567"), TongNumber("134589"), TongNumber("234567"), TongNumber("234689"), TongNumber("234789"), TongNumber("245679") ) } // 监听选中列表变化,同步更新项的选中状态 LaunchedEffect(selectedTongNumber) { tongNumberList.forEach { tn -> tn.isSelected = selectedTongNumber.contains(tn.number) } } // 初始化选中列表,先清空避免重复数据 LaunchedEffect(dataTongNumber.size) { selectedTongNumber.clear() selectedTongNumber.addAll(dataTongNumber) } val scrollState = rememberLazyListState() val coroutineScope = rememberCoroutineScope() LazyColumn( state = scrollState, contentPadding = PaddingValues(12.dp), modifier = Modifier .fillMaxWidth() .heightIn(max = 150.dp) ) { itemsIndexed( items = tongNumberList.sortedByDescending { tn -> tn.isSelected }, key = { index, tn -> tn.number } ) { index, tongNumber -> // 直接复用tongNumber的选中状态,无需额外remember变量 Row( modifier = Modifier .fillMaxWidth() .wrapContentHeight() .padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically ) { Checkbox( checked = tongNumber.isSelected, onCheckedChange = { isChecked -> tongNumber.isSelected = isChecked if (isChecked) { selectedTongNumber.add(tongNumber.number) } else { selectedTongNumber.remove(tongNumber.number) } coroutineScope.launch { scrollState.animateScrollToItem(index = selectedTongNumber.size - 1) } } ) Text( text = tongNumber.number, fontFamily = fonts, fontSize = 14.sp, color = blackPrimary ) } } }
关键修改点
- 用
remember包裹tongNumberList,确保重组时不会重新创建,保留已有状态。 - 将同步选中状态的逻辑放到监听
selectedTongNumber的LaunchedEffect中,数据源变化时立刻更新列表项并触发UI重组。 - 移除冗余的
isNumberChecked状态变量,直接使用tongNumber.isSelected作为Checkbox的选中值,保证UI与数据完全联动。 - 初始化
selectedTongNumber时先调用clear(),避免重复添加数据导致异常。
内容的提问来源于stack exchange,提问作者Nisrina Alya Putri
相关产品推荐
相关产品推荐

