Android Jetpack Compose AdapterList滚动拖拽出列表时崩溃求助
这个问题我之前在早期Compose预览版本里碰到过,确实是0.1.0-dev09版本的已知bug。从崩溃日志能看出来:当你按住屏幕滚动并把拖拽范围移出AdapterList区域时,PointerInput系统还在尝试对已经脱离布局树的Clickable组件做坐标转换,但此时组件的isAttached状态已经是false了,直接触发了IllegalStateException。
下面给你两个解决方案,优先推荐第一个:
1. 升级Jetpack Compose版本(最彻底的解决办法)
0.1.0-dev09是非常早期的预览版本,后续的dev版本(比如dev10及以上)以及后来的Alpha/Beta版本都修复了大量PointerInput和列表相关的bug。
你需要把原有的依赖替换成更高版本的Compose库,注意从dev09之后,Compose的依赖结构有小调整,这里给你两个示例:
示例1:升级到同系列的更高dev版本(比如dev15)
//Jetpack Component implementation 'androidx.ui:ui-framework:0.1.0-dev15' implementation 'androidx.ui:ui-layout:0.1.0-dev15' implementation 'androidx.ui:ui-material:0.1.0-dev15' implementation 'androidx.ui:ui-foundation:0.1.0-dev15' implementation 'androidx.ui:ui-tooling:0.1.0-dev15'
示例2:升级到更稳定的Alpha版本(推荐长期使用)
如果想往更稳定的方向升级,依赖会变成androidx.compose.ui:前缀,比如1.0.0-alpha01(后续可以选更新的Alpha/Beta版本):
implementation "androidx.compose.ui:ui:1.0.0-alpha01" implementation "androidx.compose.material:material:1.0.0-alpha01" implementation "androidx.compose.ui:ui-tooling:1.0.0-alpha01"
⚠️ 注意:升级到Alpha版本后,Clickable组件被替换成了Modifier.clickable,你的ItemSeat需要调整成这样:
@Composable fun ItemSeat(seat: Seat) { Text( text = "Seat ${seat.no}", modifier = Modifier .drawBackground(color = colorResource(id = R.color.color_cd3f34)) .fillMaxWidth() .clickable(onClick = {}) ) }
2. 临时Workaround(仅用于无法升级的场景)
如果暂时没法升级版本,可以试试在Clickable外层加一个状态检查,确保只有组件处于attached状态时才渲染可点击区域。不过这个方法比较繁琐,而且不一定能完全避免所有边缘情况:
@Composable fun ItemSeat(seat: Seat) { val isAttached = remember { mutableStateOf(true) } DisposableEffect(Unit) { onDispose { // 组件销毁时标记为未附着 isAttached.value = false } } if (isAttached.value) { Clickable( onClick = {}, modifier = Modifier .drawBackground(color = colorResource(id = R.color.color_cd3f34)) .fillMaxWidth() ) { Text(text = "Seat ${seat.no}") } } else { // 组件未附着时渲染不可点击的占位 Text( text = "Seat ${seat.no}", modifier = Modifier .drawBackground(color = colorResource(id = R.color.color_cd3f34)) .fillMaxWidth() ) } }
总的来说,强烈建议优先升级Compose版本,早期dev版本的bug真的很多,后续版本不仅修复了这类崩溃,还优化了API和性能,用起来会顺畅很多。
内容的提问来源于stack exchange,提问作者Madhav Gor

