Jetpack Compose如何将LazyColumn点击数据传递到同页面其他Composable
Jetpack Compose 同页左右栏数据传递实现方案
报错根因
你遇到的@composable invocations can only happen from the context of an @composable function报错,核心原因是:ProfileCard的点击回调是普通函数类型,运行在非Composable重组上下文里,不允许直接调用带@Composable注解的组件。Compose是声明式UI框架,所有组件的渲染都由状态驱动,不能通过事件回调动态插入组件。
实现思路
- 在父组件
Greeting中声明可观察状态,存储当前选中的照片数据 - 点击左侧列表项时,仅更新选中状态的值
- 右侧详情组件直接读取选中状态的值,自动触发重组渲染对应内容
修改后完整代码
import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @Composable fun Greeting() { // 选中状态,初始为null代表未选中任何项,也可默认赋值为photoList.first() var selectedPhoto by remember { mutableStateOf<photo?>(null) } Row( modifier = Modifier.fillMaxSize() ) { LazyColumn( modifier = Modifier .fillMaxHeight() .width(150.dp) .background(color = Color.LightGray) ) { items(photoList) { item -> ProfileCard(photo = item) { // 点击仅更新状态 selectedPhoto = item } } } // 右侧详情区域根据状态渲染 selectedPhoto?.let { photo -> photoContent( id = photo.id, owner = photo.owner, secret = photo.secret, server = photo.server, farm = photo.farm, title = photo.title, ispublic = photo.ispublic, isfriend = photo.isfriend, isfamily = photo.isfamily, url_s = photo.url_s, height_s = photo.height_s, width_s = photo.width_s ) } ?: run { // 未选中时的占位UI,可自定义 Text( text = "请选择左侧照片查看详情", modifier = Modifier.padding(32.dp) ) } } }
可选优化
可以直接修改photoContent的入参定义,直接接收photo类型的对象,不用拆分单个字段传递,代码会更简洁:
// 优化后的photoContent声明 @Composable fun photoContent(photo: photo) { // 内部逻辑无需改动,直接使用photo的各个属性即可 } // 调用处简化为 selectedPhoto?.let { photoContent(it) }
内容的提问来源于stack exchange,提问作者Saher Al-Sous
相关产品推荐
相关产品推荐

