itemList.reverse()
itemList
是viewModel
中的mutableStateListOf()
对象,上面的行抛出在给定异常下面:
java.util.ConcurrentModificationException
at androidx.compose.runtime.snapshots.StateListIterator.validateModification(SnapshotStateList.kt:278)
at androidx.compose.runtime.snapshots.StateListIterator.set(SnapshotStateList.kt:271)
at java.util.Collections.reverse(Collections.java:435)
at kotlin.collections.CollectionsKt___CollectionsJvmKt.reverse(_CollectionsJvm.kt:43)
at in.rachika.composetest2.Tests.LazyColumnHeaderTest$MainScreenWithChildList$1$2.invoke(LazyColumnHeaderTest.kt:114)
at in.rachika.composetest2.Tests.LazyColumnHeaderTest$MainScreenWithChildList$1$2.invoke(LazyColumnHeaderTest.kt:111)
我无法弄清楚如何逆转或洗牌mutableStateListOf()
对象
reverse()
在孤立的情况下工作得很好,但是我的LazyColumn
有stickyHeader()
和SwipeToDismiss()
,不知道这可能会造成问题。
模型
data class TestModel(
val isHeader: Boolean,
val UniqueKey: UUID,
val GroupId: UUID,
val GroupName: String,
val ItemName: String,
val children: MutableList<TestModel>,
var isExpanded: Boolean = false)
ViewModel
class TestViewModel: ViewModel() {
var itemList = mutableStateListOf<TestModel>()
init {
viewModelScope.launch(Dispatchers.IO){
loadList()
}
}
private fun loadList() {
for(i in 0..20){
val groupName = "${i + 1}. STICKY HEADER #"
val groupUUID = UUID.randomUUID()
val childList = mutableListOf<TestModel>()
for(t in 0..Random.nextInt(10, 20)){
childList.add(TestModel(
isHeader = false,
UniqueKey = UUID.randomUUID(),
GroupId = groupUUID,
GroupName = groupName,
ItemName = "${t + 1}. This is an CHILD ITEM... #${i + 1} - ${Random.nextInt(1001, 5001)}",
children = ArrayList()
)
)
}
viewModelScope.launch(Dispatchers.Main){
itemList.add(TestModel(
isHeader = true,
UniqueKey = UUID.randomUUID(),
GroupId = groupUUID,
GroupName = groupName,
ItemName = "",
children = childList
))
}
}
}
fun addChildren(testModel: TestModel, onCompleted: (startIndex: Int) -> Unit){
if(testModel.children.count() > 0){
var index = itemList.indexOf(testModel)
testModel.children.forEach { tItem ->
itemList.add(index + 1, tItem)
index++
}
testModel.apply {
isExpanded = true
children.clear()
}
onCompleted(index)
}
}
fun removeChildren(testModel: TestModel, onCompleted: (startIndex: Int) -> Unit){
val startIndex = itemList.indexOf(testModel) + 1
while (startIndex < itemList.size && !itemList[startIndex].isHeader){
testModel.children.add(itemList.removeAt(startIndex))
}
if(testModel.children.count() > 0){
testModel.isExpanded = false
onCompleted(startIndex - 1)
}
}}
可组合函数
@Composable
fun MainScreenWithChildList(testViewModel: TestViewModel = viewModel()) {
val lazyColumnState = rememberLazyListState()
var reverseList by remember { mutableStateOf(false) }
if (reverseList) {
LaunchedEffect(Unit) {
delay(1000)
testViewModel.itemList.reverse()
}
}
Box(modifier = Modifier.fillMaxSize()) {
LazyColumn(
state = lazyColumnState,
modifier = Modifier.fillMaxSize()
) {
testViewModel.itemList.forEach { testModel ->
when (testModel.isHeader) {
true -> {
stickyHeader(key = testModel.UniqueKey) {
HeaderLayout(testModel = testModel) { testModel ->
if (testModel.isExpanded) {
testViewModel.removeChildren(testModel) {}
} else {
testViewModel.addChildren(testModel) {}
}
}
}
}
false -> {
item(key = testModel.UniqueKey) {
val dismissState = rememberDismissState()
if (dismissState.isDismissed(DismissDirection.EndToStart) || dismissState.isDismissed(
DismissDirection.StartToEnd
)
) {
if (dismissState.currentValue != DismissValue.Default) {
LaunchedEffect(Unit) {
dismissState.reset()
}
}
}
SwipeToDismiss(
state = dismissState,
directions = setOf(
DismissDirection.StartToEnd,
DismissDirection.EndToStart
),
dismissThresholds = { direction ->
FractionalThreshold(if (direction == DismissDirection.StartToEnd || direction == DismissDirection.EndToStart) 0.25f else 0.5f)
},
background = { SwipedItemBackground(dismissState = dismissState) },
dismissContent = {
ItemScreen(
modifier = Modifier
.fillMaxWidth()
.animateItemPlacement(animationSpec = tween(600)),
elevation = if (dismissState.dismissDirection != null) 16 else 0,
testModel = testModel
)
}
)
}
}
}
}
}
Button(
onClick = {
reverseList = true
},
modifier = Modifier.align(Alignment.BottomCenter)
) {
Text(text = "Reverse")
}
}
}
@Composable
fun ItemScreen(modifier: Modifier, elevation: Int, testModel: TestModel) {
Card(
modifier = modifier,
//elevation = animateDpAsState(elevation.dp).value
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
text = testModel.ItemName + " ="
)
}
}
@Composable
fun SwipedItemBackground(dismissState: DismissState) {
val direction = dismissState.dismissDirection ?: return
val color by animateColorAsState(
targetValue = when (dismissState.targetValue) {
DismissValue.Default -> Color.LightGray
DismissValue.DismissedToEnd -> Color.Green
DismissValue.DismissedToStart -> Color.Red
}
)
val icon = when (direction) {
DismissDirection.StartToEnd -> Icons.Default.Done
DismissDirection.EndToStart -> Icons.Default.Delete
}
val scale by animateFloatAsState(
if (dismissState.targetValue == DismissValue.Default) 0.75f else 1.5f
)
val alignment = when (direction) {
DismissDirection.StartToEnd -> Alignment.CenterStart
DismissDirection.EndToStart -> Alignment.CenterEnd
}
Box(
modifier = Modifier
.fillMaxSize()
.background(color)
.padding(start = 12.dp, end = 12.dp),
contentAlignment = alignment
) {
Icon(icon, contentDescription = "Icon", modifier = Modifier.scale(scale))
}
}
@Composable
fun HeaderLayout(testModel: TestModel, onExpandClicked: (testModel: TestModel) -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
.background(
color = Color.LightGray,
shape = RoundedCornerShape(8.dp)
)
.padding(horizontal = 32.dp, vertical = 16.dp),
horizontalArrangement = SpaceBetween
) {
Text(text = testModel.GroupName)
TextButton(onClick = { onExpandClicked(testModel) }) {
Text(text = if (testModel.isExpanded) "Collapse" else "Expand")
}
}
}
上面的是完全可复制的代码。请复制粘贴并尝试
发布于 2022-02-15 06:39:29
当列表大小很小时,reverse
似乎工作得很好,但是当项目数量很大时,它就会崩溃。我能够用下面的MRE复制这个
val list = remember { (1..100).toList().toMutableStateList() }
LaunchedEffect(Unit) {
delay(1.seconds)
list.reverse()
}
Text(list.toList().toString())
和已报告这个组成问题跟踪器,星光它可以更快地解决。
在此之前,您可以手动反转它,如下所示:
val newItems = list.reversed()
list.clear()
list.addAll(newItems)
https://stackoverflow.com/questions/71121504
复制相似问题