NavHost 中 LazyColumn 中的 Android Compose 约束布局:错误 - 对未放置的项目调用了 Replace()

问题描述 投票:0回答:1

我有一个大型项目,我遇到了这个异常 - replace() 调用了未放置的项目。我能够将问题的根源缩小到在 NavHost 中具有 a 约束布局。我创建了一个极其简化的项目,它是可复制的。我强调简化,因为这里的约束布局甚至没有正确使用,没有应用约束 - 这是故意的,为了简化并表明在这种情况下并不重要(在实际项目中,所有约束都已到位) 这里有指向简化项目的 Github 链接 另外,下面是相关代码片段。 如果我直接调用 MainContent() ,没有问题。如果我通过 NavHost 调用,当我滚动惰性列时,我会崩溃。

问题

  1. 代码有问题吗?
  2. 如果这是一个 Compose 错误,我尝试了许多不同版本的库 - 它一定已经存在很长时间了。我看到了几个关于此问题的 stackoveflow 问题,但没有一个将崩溃与 navhost 联系起来 - navhost 是否只是 bug 出现的条件之一?

java.lang.IllegalStateException:对不存在的项目调用了replace() 放置 在 androidx.compose.ui.node.LayoutNodeLayoutDelegate$LookaheadPassDelegate.replace(LayoutNodeLayoutDelegate.kt:1569) 在 androidx.compose.ui.node.LayoutNode.lookaheadReplace$ui_release(LayoutNode.kt:923) 在 androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded

具体来说,这是来自 Compose 的 Layoutnode.kt 中的代码:

internal fun lookaheadReplace() {
        if (intrinsicsUsageByParent == UsageByParent.NotUsed) {
            // This LayoutNode may have asked children for intrinsics. If so, we should
            // clear the intrinsics usage for everything that was requested previously.
            clearSubtreePlacementIntrinsicsUsage()
        }
        **lookaheadPassDelegate!!.replace()**
    }

活动:

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
           // MainContent() -- this works
            val navController = rememberNavController()
            // with NavHost, it crashes.
            NavHost(
                navController,
                startDestination =  NavRoutes.MainRoute.name
            ) {
                mainGraph()
            }
        }
    }
}

主图:

fun NavGraphBuilder.mainGraph(
) {
    navigation(startDestination = MainNavOption.Main.name, route = NavRoutes.MainRoute.name) {
        composable(MainNavOption.Main.name){
            MainContent()
        }
    }
}

主要内容:

@Composable
fun MainContent() {
    WhyConstraintTheme {
        val listState = rememberLazyListState()
        // A surface container using the 'background' color from the theme
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colorScheme.background
        ) {
            var listItems = mutableListOf<ElementHolder>()
            for (i in 1.rangeTo(149)) {
                listItems.add(ElementHolder(i.toString()))
            }
            BoxWithConstraints(Modifier.fillMaxSize()) {
                LazyColumn(
                    state = listState,
                    contentPadding = PaddingValues(1.dp),
                    verticalArrangement = Arrangement.Center
                ) {
                    items(listItems) { item: ElementHolder ->
                        ElementListItem(
                            element = item.itemDescription,
                        )
                    }
                }
            }
        }
    }
}

H 元素

@可组合 有趣的元素列表项( 元素:字符串, ){

ConstraintLayout() {
    val (
        divider, year, description, image,
        overflow
    ) = createRefs()

    Text(
        text = "element:  {$element}",
        modifier = Modifier.constrainAs(year) {
            linkTo(
                start = parent.start,
                end = parent.end,
            )
        }
    )
}

}

使用的版本(顺便说一句,尝试了许多不同的版本,回到了许多以前的版本)

valmaterial_version =“1.5.4” 实现 ("androidx.compose.material:material:$material_version")

implementation ("androidx.compose.material:material-icons-extended:$material_version")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.activity:activity-compose:1.8.1")
implementation(platform("androidx.compose:compose-bom:2023.10.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation ("androidx.constraintlayout:constraintlayout-compose:1.0.1")

实现(“androidx.navigation:navigation-compose:2.7.5”)

编辑: 崩溃的另一个触发因素是 AnimatedContent。如果您将 LazyColumn 与约束布局包装在 AnimatedContent(而不是 NavHost)中,则会发生相同的崩溃。因此,最终的根本原因可能与 NavHost 和 AnimatedContent 内的动画有关 - NavHost 内的 Composable 具有 AnimatedContentScope。

android kotlin android-studio navigation android-jetpack-compose
1个回答
0
投票

针对崩溃的修复似乎是将

ConstraintLayout
1.0.1
升级到
1.1.0-alpha13

© www.soinside.com 2019 - 2024. All rights reserved.