[英]How to show snackbars from Composables or ViewModels on a multi-module, single activity, Compose only, project
在多模块、单一活动、仅撰写项目上显示 Snackbar 的最佳方式是什么?
这是项目依赖图的样子:
该项目的唯一活动是在app
模块内,它只是将NavHost
设置为 content 。
每个feature
模块都提供一个可组合屏幕的列表,这些屏幕将显示在NavHost
。
每个屏幕都有自己的Scaffold
,因此它可以轻松地从每个屏幕的ViewModel
显示 Snackbars 。
有一个特殊的feature
模块, feature-debug
,它显示在单个屏幕上, 每个feature
模块提供的可组合列表,称为调试部分。 它用于允许任何feature
模块在调试屏幕内自动显示一些设置。
每个调试部分都有自己的ViewModel
因此它的工作方式与 Screen 完全一样。 但它缺少 Scaffold,因为它只占用屏幕的一部分:
+-------------------------+
| Debug screen |
|-------------------------+
| |
| Feature A debug section |
| |
|------------------------ +
| |
| Feature B debug section |
| |
|------------------------ +
| |
| Feature C debug section |
| |
|------------------------ +
| |
| Feature D debug section |
| |
+------------------------ +
因此,我不确定如何在feature-debug
屏幕的 Scaffold 上显示 Snackbar,从在另一个feature
模块中声明的可组合项中,该feature
模块对feature-debug
中的任何类不可见。
CompositionLocal
可用于隐式地通过组合树传递数据。
首先要做的是声明一个必须对提供者和消费者可见的变量(在我的例子中,我在core-ui
模块中创建了它):
val LocalSnackbarHostState = compositionLocalOf<SnackbarHostState> { error("No SnackbarHostState provided") }
然后提供者应该用CompositionLocalProvider
包装它的孩子:
val scaffoldState = rememberScaffoldState()
CompositionLocalProvider(
LocalSnackbarHostState provides scaffoldState.snackbarHostState
) {
Scaffold(
[...]
最后,孩子们可以获取访问变量LocalSnackbarHostState
的SnackbarHostState
实例:
val snackbarHostState = LocalSnackbarHostState.current
我只会为您的整个应用程序使用一个小吃店。 它需要包含在 UI 层次结构的根级别,并可以通过全局对象访问。 这可以通过使用继承自 Application 的类并在该类中放置一个方法来处理显示小吃栏来完成。
有一个示例应用程序显示了这是如何完成的。 演示应用程序可以在以下位置下载:
https://github.com/JohannBlake/Jetmagic
运行应用程序时,打开导航托盘并选择任何导航项。 在出现的屏幕上,单击标有Return value from another screen
的按钮。 这将带您进入另一个屏幕,您可以在其中选择一个项目并返回上一个屏幕。 所选项目将显示在小吃店中。 这个小吃店在整个应用程序中都是全球性的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.