目前只有外部List会触发重组。当内部列表中的字符串也被更改/添加时,如何触发重组?
private var data by mutableStateOf<List<List<StringObject>>>(
// Initialize with some sample data (20 rows, 10 columns)
List(20) { outerIndex ->
List(10) { innerIndex ->
val value = "Value ${outerIndex * 10 + innerIndex + 1}"
val imageUrl = if (innerIndex % 2 == 0)
"https://example.com/image${innerIndex + 1}.jpg"
else
null
StringObject(value, imageUrl)
} as List<StringObject>
}
)
我尝试更换这个
mutableStateOf<List<List<StringObject>>>
这样:
mutableStateOf<List<MutableList<StringObject>>>
但这会使应用程序因并发修改而崩溃。我是 Compose 的新手,老实说,由于所有这些不可变和状态的东西,它很糟糕。新语言应该在内部自行管理这些东西。
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1029)
at java.util.ArrayList$Itr.next(ArrayList.java:982)
at com.example.composetablee.MainActivity.addColumn(MainActivity.kt:143)
at com.example.composetablee.MainActivity.access$addColumn(MainActivity.kt:28)
at com.example.composetablee.MainActivity$onCreate$1$1$1$1$1$1$1.invoke(MainActivity.kt:51)
at com.example.composetablee.MainActivity$onCreate$1$1$1$1$1$1$1.invoke(MainActivity.kt:51)
at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$1$2.invoke-k-4lQ0M(Clickable.kt:167)
at androidx.compose.foundation.ClickableKt$clickable$4$gesture$1$1$2.invoke(Clickable.kt:156)
at androidx.compose.foundation.gestures.TapGestureDetectorKt$detectTapAndPress$2$1.invokeSuspend(TapGestureDetector.kt:255)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:328)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:566)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.dispatchPointerEvent(SuspendingPointerInputFilter.kt:456)
at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:469)
at androidx.compose.ui.node.BackwardsCompatNode.onPointerEvent-H0pRuoY(BackwardsCompatNode.kt:374)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:314)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:301)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:301)
at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:183)
at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:102)
at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:98)
at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1361)
at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1307)
at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1246)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3324)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2998)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3324)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2998)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3324)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2998)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3324)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2998)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:776)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1967)
at android.app.Activity.dispatchTouchEvent(Activity.java:4522)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:734)
at android.view.View.dispatchPointerEvent(View.java:16476)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:8490)
如何处理不可变列表,因为它不允许我在其中添加内容?制作可变副本似乎资源成本高昂,尤其是如果有大量列表数据的话。
如果要创建列表的列表,可以使用以下代码:
val parentList = mutableStateListOf<List<String>>(listOf("A", "B"), listOf("M", "N"), listOf("X", "Y"))
要将新列表添加到
parentList
,请使用
parentList.add(listOf("1", "2"))
要将新元素添加到
parentList
内的列表中,请执行
parentList[2] = parentList[2].plus("Z") // parentList[2] now contains X, Y, Z
通过这种方法,Jetpack Compose 应该能够正确获取对
parentList
或任何嵌套列表所做的更改。
关于
ConcurrentModificationException
,请检查 MainActivity 中的 addColumn
函数。问题就在那里触发。