LazyColumn 开始在列表大小更改时显示 IndexOutOfBoundsExeption

LazyColumn started showing IndexOutOfBoundsExeption on list size change

提问人:oljik 提问时间:10/29/2023 最后编辑:oljik 更新时间:10/30/2023 访问量:51

问:

LazyColumn 在列表大小减小时停止正确重构,显示 IndexOutOfBoundsExeption。

这是我在项目中尝试的测试代码

val data  = remember {
  mutableStateOf(
    listOf("1", "2")
  )
}

Column(modifier = Modifier.fillMaxSize()) {
                Button(onClick = {
                    data.value = listOf("2")
                }) {
                    Text("test")
                }
                    LazyColumn(
                        modifier = Modifier
                            .background(color = Color.Transparent),
                    ) {
                        items(items = data.value) { item ->
                            Text(text = "123")
                        }
                    }
          }

以下是我使用的常用库的版本:

dependencies {
    def composeBom = platform('androidx.compose:compose-bom:2023.10.01')
    implementation composeBom
    androidTestImplementation composeBom
    implementation "androidx.compose.ui:ui"
    implementation "androidx.compose.ui:ui-util"
    implementation "androidx.compose.ui:ui-tooling-preview"
    implementation "androidx.compose.material3:material3:1.2.0-alpha10"
    implementation "androidx.compose.material:material-icons-extended"
    debugImplementation "androidx.compose.ui:ui-tooling"
    androidTestImplementation "androidx.compose.ui:ui-test-junit4"

    implementation("androidx.activity:activity-compose:1.8.0")
    implementation('androidx.navigation:navigation-compose:2.7.4')
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2'
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")

    implementation 'androidx.core:core-ktx:1.12.0'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.1'

    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-compiler:$hilt_version"
    implementation "androidx.hilt:hilt-navigation-compose:1.0.0"

几周前,在开始升级插件和库版本之前,它运行良好。但是,我在降级时遇到了麻烦,因为我已经使用新版本编写了许多代码。此外,我没有以前使用的版本列表

更新: 以下是完整的错误消息:

FATAL EXCEPTION: main
Process: com.tim.android, PID: 29817
java.lang.IndexOutOfBoundsException: Index 1, size 1
at androidx.compose.foundation.lazy.layout.MutableIntervalList.checkIndexBounds(IntervalList.kt:183)
at androidx.compose.foundation.lazy.layout.MutableIntervalList.get(IntervalList.kt:166)
at androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.getKey(LazyLayoutIntervalContent.kt:86)
at androidx.compose.foundation.lazy.LazyListItemProviderImpl.getKey(LazyListItemProvider.kt:85)
at androidx.compose.foundation.lazy.LazyListMeasuredItemProvider.getAndMeasure(LazyListMeasuredItemProvider.kt:46)
at androidx.compose.foundation.lazy.LazyListMeasureKt.createItemsAfterList(LazyListMeasure.kt:418)
at androidx.compose.foundation.lazy.LazyListMeasureKt.measureLazyList-50ZNEM8(LazyListMeasure.kt:278)
at androidx.compose.foundation.lazy.LazyListKt$rememberLazyListMeasurePolicy$1$1.invoke-0kLqBqw(LazyList.kt:328)
at androidx.compose.foundation.lazy.LazyListKt$rememberLazyListMeasurePolicy$1$1.invoke(LazyList.kt:193)
at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$3$2$1.invoke-0kLqBqw(LazyLayout.kt:107)
at androidx.compose.foundation.lazy.layout.LazyLayoutKt$LazyLayout$3$2$1.invoke(LazyLayout.kt:100)
at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:708)
at androidx.compose.ui.node.InnerNodeCoordinator$LookaheadDelegateImpl.measure-BRTryo0(InnerNodeCoordinator.kt:81)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2.invoke-3p2s80s(AndroidOverscroll.kt:584)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$2.invoke(AndroidOverscroll.kt:583)
at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(LayoutModifier.kt:291)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator$LookaheadDelegateForLayoutModifierNode.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:64)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1.invoke-3p2s80s(AndroidOverscroll.kt:568)
at androidx.compose.foundation.AndroidOverscrollKt$StretchOverscrollNonClippingLayer$1.invoke(AndroidOverscroll.kt:567)
at androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(LayoutModifier.kt:291)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator$LookaheadDelegateForLayoutModifierNode.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:64)
at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:646)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator$LookaheadDelegateForLayoutModifierNode.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:64)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performLookaheadMeasure$1.invoke(LayoutNodeLayoutDelegate.kt:1622)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performLookaheadMeasure$1.invoke(LayoutNodeLayoutDelegate.kt:1621)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2303)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:496)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:256)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:111)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release$default(OwnerSnapshotObserver.kt:105)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performLookaheadMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1621)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performLookaheadMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1289)
at androidx.compose.ui.node.LayoutNode.lookaheadRemeasure-_Sx5XlM$ui_release(LayoutNode.kt:1126)
at androidx.compose.ui.node.LayoutNode.lookaheadRemeasure-_Sx5XlM$ui_release$default(LayoutNode.kt:1120)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.doLookaheadRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:313)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:478)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.onlyRemeasureIfScheduled(MeasureAndLayoutDelegate.kt:564)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:590)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:597)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:597)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:597)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:597)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:597)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtreeInternal(MeasureAndLayoutDelegate.kt:597)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.forceMeasureTheSubtree(MeasureAndLayoutDelegate.kt:553)
at androidx.compose.ui.platform.AndroidComposeView.forceMeasureTheSubtree(AndroidComposeView.android.kt:991)
at androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1299)
at androidx.compose.ui.node.LayoutNode.lookaheadRemeasure-_Sx5XlM$ui_release(LayoutNode.kt:1126)
at androidx.compose.ui.node.LayoutNode.lookaheadRemeasure-_Sx5XlM$ui_release$default(LayoutNode.kt:1120)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.doLookaheadRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:313)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureOnly(MeasureAndLayoutDelegate.kt:526)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureLookaheadRootsInSubtree(MeasureAndLayoutDelegate.kt:394)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureLookaheadRootsInSubtree(MeasureAndLayoutDelegate.kt:397)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureLookaheadRootsInSubtree(MeasureAndLayoutDelegate.kt:397)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureLookaheadRootsInSubtree(MeasureAndLayoutDelegate.kt:397)
at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureOnly(MeasureAndLayoutDelegate.kt:381)
at androidx.compose.ui.platform.AndroidComposeView.onMeasure(AndroidComposeView.android.kt:1056)
at android.view.View.measure(View.java:27129)
at androidx.compose.ui.platform.AbstractComposeView.internalOnMeasure$ui_release(ComposeView.android.kt:302)
at androidx.compose.ui.platform.AbstractComposeView.onMeasure(ComposeView.android.kt:289)
at android.view.View.measure(View.java:27129)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
at android.view.View.measure(View.java:27129)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
at android.view.View.measure(View.java:27129)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:1277)
at android.view.View.measure(View.java:27129)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4528)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3525)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2911)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10458)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1108)
at android.view.Choreographer.doCallbacks(Choreographer.java:866)
at android.view.Choreographer.doFrame(Choreographer.java:797)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1092)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8663)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

更新2:我发现在NavHost之外使用此屏幕可以正常工作。在同一屏幕上测试了NavHost内部和外部的相同视图:

Column(modifier = Modifier.fillMaxSize()) {
  Spacer(modifier = Modifier.weight(1f))
    NavHost(
      navController = navController,
      startDestination = Screen.Home.route,
    ) {
      composable(route = Screen.Home.route) {
        ListView()
      }
    }
    Spacer(modifier = Modifier.weight(1f))
    ListView()
    Spacer(modifier = Modifier.weight(1f))
}
android-jetpack-compose kotlin-flow

评论

0赞 Ayman Ait 10/29/2023
我认为最好添加整个错误,因为我刚刚测试了您发布的代码,它对我来说工作正常

答:

1赞 oljik 10/30/2023 #1

将 navigation-compose 降级到 2.6.0 帮助我解决了这个问题。可能降级到 material3:1.2.0-alpha06 适用于我前段时间使用的 2.7.0+。 我正在使用 material3 库的许多新的实验性和 alpha 功能,这些功能强制使用 compose-foundation 的 alpha 版本,因此降级导航目前对我来说是更好的解决方案。