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