我有一个大项目,在那里我得到了这个例外-101我能够将问题的根源缩小到a Constraint Layout within a NavHost.,我创建了一个非常simplified的项目,在那里它是可重现的.我强调简化,BC这里甚至没有正确使用ConraintLayout,没有应用约束--这是故意的,目的是简化并表明它在这种情况下并不重要(在实际的项目中,所有的约束都到位了) Github link to the simplified project here个 另外,下面还有相关的代码片段. 如果我直接调用MainContent(),没有问题.如果我通过Navhost调用,当我滚动浏览懒惰列时,我会崩溃.
问题
- 代码有什么问题吗?
- 如果这是一个编写错误,我try 了许多不同版本的库-它肯定已经在那里很长时间了.我看到了几个关于这个问题的stackoveflow问题,但没有一个问题与Navhost有关-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
可组合的 Fun ElementListItem( 元素:字符串、 ){
ConstraintLayout() {
val (
divider, year, description, image,
overflow
) = createRefs()
Text(
text = "element: {$element}",
modifier = Modifier.constrainAs(year) {
linkTo(
start = parent.start,
end = parent.end,
)
}
)
}
}
使用的版本(顺便说一句,try 了许多不同的版本,返回到许多以前的版本)
VAL MATERIAL_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.如果在AnimatedContent(而不是NavHost)中使用约束布局包装LazyColumn,则会发生相同的崩溃.因此,最终的根本原因可能与Navhost和AnimatedContent中的动画有关-Navhost中的Composable具有AnimatedContent Scope.