如何在Jetpack Compose中传递Scaffold内FAB的点击事件到其他页面?
你当前的核心问题是顶层Scaffold的FAB点击事件没有和目标页面的回调关联起来,参照Now In Android的架构思路,用**共享流(SharedFlow)**就能实现跨组件的事件传递,具体修改步骤如下:
1. 在LPlusAppState中添加事件触发器
先在LPlusAppState类里新增一个共享流,用来传递FAB的点击事件:
class LPlusAppState( // 保留原有参数 ) { // 创建可发送单次事件的共享流 private val _readerTrigger = MutableSharedFlow<Unit>(extraBufferCapacity = 1) val readerTrigger = _readerTrigger.asSharedFlow() // 供顶层FAB调用的触发方法 fun triggerReader() { _readerTrigger.tryEmit(Unit) } // 保留原有方法和状态 }
2. 修改顶层Scaffold的FAB点击逻辑
在LPlusApp组件里,把FAB的onClick改成调用AppState的触发方法,同时可以删掉LPlusApp参数里的onReaderClick: () -> Unit:
SmallFloatingActionButton(onClick = { appState.triggerReader() }) { Icon(Icons.Filled.PlayArrow, contentDescription = "") }
3. 在UniversalisRoute中监听事件并触发弹窗
给UniversalisRoute添加appState: LPlusAppState参数,用LaunchedEffect监听共享流事件,触发你的ModalBottomSheet:
@ExperimentalMaterial3AdaptiveApi @Composable fun UniversalisRoute( onBackClick: () -> Unit, modifier: Modifier = Modifier, viewModel: UniversalisViewModel = hiltViewModel(), appState: LPlusAppState, // 新增参数 ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() // 监听阅读器触发事件 LaunchedEffect(Unit) { appState.readerTrigger.collect { Timber.d("Launch ModalBottomSheet with TTS") // 这里写打开ModalBottomSheet的具体逻辑 } } UniversalisScreen( uiState = uiState, modifier = modifier, onBackClick = onBackClick, // 如果Screen层需要处理事件,也可以把回调传递进去 ) }
4. 确保UniversalisRoute能拿到AppState
在LPlusApp的导航部分(即Scaffold的content区域),跳转到UniversalisRoute时把appState传进去,假设用NavHost的话示例如下:
NavHost( navController = appState.navController, startDestination = ... ) { composable(route = "universalis") { UniversalisRoute( onBackClick = { appState.navController.popBackStack() }, appState = appState // 传递AppState ) } // 其他路由配置 }
最后调整MainActivity的调用
因为LPlusApp不再需要onReaderClick参数,所以MainActivity里的调用简化为:
LPlusApp(appState)
这样修改后,点击顶层FAB时,AppState会发送事件,UniversalisRoute会监听并触发TTS阅读器弹窗,完美实现跨页面事件传递,也符合Now In Android的架构设计。
内容的提问来源于stack exchange,提问作者A. Cedano
相关产品推荐
相关产品推荐

