Android Compose:LazyVerticalGrid添加verticalScroll后崩溃报错
问题:Compose中LazyVerticalGrid添加verticalScroll导致崩溃
在Android Compose开发中,我编写的AppDrawer组件用LazyVerticalGrid展示应用列表,原生滚动卡顿,尝试加Modifier.verticalScroll(rememberScrollState())后应用直接崩溃,抛出IllegalStateException,提示垂直滚动组件被赋予无限高度约束。已确认布局上下无其他滚动组件,设置固定高度也没解决问题。
相关代码
class AppDrawer(private val context: Context){ lateinit var listener: () -> Unit private val pm: PackageManager = context.packageManager private var appPrerender: List<AppPrerender>?=null; init { CoroutineScope(Dispatchers.Default).launch { // 出于性能考虑用协程 appPrerender = pm.getInstalledApplications(PackageManager.GET_META_DATA).toList() .filter { pm.getLaunchIntentForPackage(it.packageName) != null } .map { AppPrerender(it.loadLabel(pm).toString(), it.loadIcon(pm).toBitmap(100, 100).asImageBitmap(), it.packageName) { context.startActivity( pm.getLaunchIntentForPackage(it.packageName) ) } } } } @Composable fun Compose() { LazyVerticalGrid(GridCells.Fixed(6), Modifier // .verticalScroll(rememberScrollState()) ) { if (appPrerender != null) { items(appPrerender!!, key = { it.packageName }) { it.Render() } } } } } class AppPrerender(private val name: String, private val icon: ImageBitmap, val packageName: String, private val launch: ()->Unit){ @Composable fun Render(){ App(name, icon, launch) } } @Composable fun App(name: String, icon: ImageBitmap, launch: ()->Unit){ Image(icon, contentDescription = name, Modifier.padding(0.dp, 20.dp).clickable { launch() }) }
报错信息
FATAL EXCEPTION: main (Ask Gemini) Process: com.myxoz.home, PID: 32177 java.lang.IllegalStateException: Vertically scrollable component was measured with an infinity maximum height constraints, which is disallowed. One of the common reasons is nesting layouts like LazyColumn and Column(Modifier.verticalScroll()). If you want to add a header before the list of items please add a header as a separate item() before the main items() inside the LazyColumn scope. There are could be other reasons for this to happen: your ComposeView was added into a LinearLayout with some weight, you applied Modifier.wrapContentSize(unbounded = true) or wrote a custom layout. Please try to remove the source of infinite constraints in the hierarchy above the scrolling container.
中文翻译:
java.lang.IllegalStateException: 垂直滚动组件被赋予了无限高度约束,这是不允许的。常见原因包括嵌套LazyColumn和Column(Modifier.verticalScroll())这类布局。如果想在列表前加头部,请在LazyColumn范围内的主items()之前单独加一个item()作为头部。还有其他可能:你的ComposeView被放到带weight属性的LinearLayout里,你用了Modifier.wrapContentSize(unbounded = true),或者自定义了布局。请尝试移除滚动容器上层布局中导致无限约束的原因。
解决方案
别给LazyVerticalGrid加额外的verticalScroll
LazyVerticalGrid本身自带垂直滚动逻辑,手动加verticalScroll会造成滚动冲突,同时让父容器无法正确计算高度,传递无限约束给组件,直接导致崩溃。优化原生滚动卡顿问题
卡顿大概率是数据加载或列表项渲染的问题,可从这几点调整:- 绑定生命周期加载数据:原init块里的协程没绑定生命周期,改用
LaunchedEffect在Composable中执行,避免内存泄漏:@Composable fun Compose() { var appPrerender by remember { mutableStateOf<List<AppPrerender>?>(null) } LaunchedEffect(Unit) { appPrerender = pm.getInstalledApplications(PackageManager.GET_META_DATA).toList() .filter { pm.getLaunchIntentForPackage(it.packageName) != null } .map { AppPrerender( it.loadLabel(pm).toString(), it.loadIcon(pm).toBitmap(100, 100).asImageBitmap(), it.packageName ) { context.startActivity(pm.getLaunchIntentForPackage(it.packageName)) } } } // 后续LazyVerticalGrid代码不变 } - 固定列表项尺寸:给
App组件里的Image加固定size,减少布局重排:@Composable fun App(name: String, icon: ImageBitmap, launch: ()->Unit){ Image( icon, contentDescription = name, Modifier .size(48.dp) // 固定图标尺寸 .padding(0.dp, 20.dp) .clickable { launch() } ) } - 明确LazyVerticalGrid的高度约束:确保父容器给它明确的高度限制,比如用
fillMaxHeight():LazyVerticalGrid( columns = GridCells.Fixed(6), modifier = Modifier.fillMaxHeight() ) { // 列表项代码不变 }
- 绑定生命周期加载数据:原init块里的协程没绑定生命周期,改用
内容的提问来源于stack exchange,提问作者Myxoz
相关产品推荐
相关产品推荐

