[英]How to show snackbars from Composables or ViewModels on a multi-module, single activity, Compose only, project
What's the best way to show a Snackbar on a multi-module, single activity, Compose only project?在多模块、单一活动、仅撰写项目上显示 Snackbar 的最佳方式是什么?
This is how the project dependency graph looks like:这是项目依赖图的样子:
The only activity of the project is inside the app
module and it just sets the NavHost
as content .该项目的唯一活动是在
app
模块内,它只是将NavHost
设置为 content 。
Each feature
module provides a list of composable screens that will be shown on the NavHost
.每个
feature
模块都提供一个可组合屏幕的列表,这些屏幕将显示在NavHost
。
Each screen has its own Scaffold
, so it can easily show Snackbars from the each screen's ViewModel
.每个屏幕都有自己的
Scaffold
,因此它可以轻松地从每个屏幕的ViewModel
显示 Snackbars 。
There is a special feature
module, feature-debug
, that shows on a single screen, a list of composable provided by each feature
module , that are called debug sections.有一个特殊的
feature
模块, feature-debug
,它显示在单个屏幕上, 每个feature
模块提供的可组合列表,称为调试部分。 It is used to allow any feature
module to show automatically some settings inside the debug screen.它用于允许任何
feature
模块在调试屏幕内自动显示一些设置。
Each debug section has its own ViewModel
so it works exactly like a Screen.每个调试部分都有自己的
ViewModel
因此它的工作方式与 Screen 完全一样。 But it's missing a Scaffold, since it only takes a portion of the screen:但它缺少 Scaffold,因为它只占用屏幕的一部分:
+-------------------------+
| Debug screen |
|-------------------------+
| |
| Feature A debug section |
| |
|------------------------ +
| |
| Feature B debug section |
| |
|------------------------ +
| |
| Feature C debug section |
| |
|------------------------ +
| |
| Feature D debug section |
| |
+------------------------ +
So I'm not sure how can I show a Snackbar on the Scaffold of the feature-debug
screen, from a composable that is declared inside another feature
module that has no visibility of the any class inside feature-debug
.因此,我不确定如何在
feature-debug
屏幕的 Scaffold 上显示 Snackbar,从在另一个feature
模块中声明的可组合项中,该feature
模块对feature-debug
中的任何类不可见。
CompositionLocal
can be used to pass data through the composition tree implicitly. CompositionLocal
可用于隐式地通过组合树传递数据。
The first thing to do is to declare a variable that must be visible by provider and consumers (in my case, I created it inside the core-ui
module):首先要做的是声明一个必须对提供者和消费者可见的变量(在我的例子中,我在
core-ui
模块中创建了它):
val LocalSnackbarHostState = compositionLocalOf<SnackbarHostState> { error("No SnackbarHostState provided") }
Then the provider should wrap its children with a CompositionLocalProvider
:然后提供者应该用
CompositionLocalProvider
包装它的孩子:
val scaffoldState = rememberScaffoldState()
CompositionLocalProvider(
LocalSnackbarHostState provides scaffoldState.snackbarHostState
) {
Scaffold(
[...]
And finally the children can grab an instance of the SnackbarHostState
accessing the variable LocalSnackbarHostState
:最后,孩子们可以获取访问变量
LocalSnackbarHostState
的SnackbarHostState
实例:
val snackbarHostState = LocalSnackbarHostState.current
I would only use a single snackbar for your entire app.我只会为您的整个应用程序使用一个小吃店。 It needs to be included at the root level of your UI hierarchy and accessible through a global object.
它需要包含在 UI 层次结构的根级别,并可以通过全局对象访问。 This can be done by using a class that inherits from Application and placing a method inside that class to handle displaying the snackbar.
这可以通过使用继承自 Application 的类并在该类中放置一个方法来处理显示小吃栏来完成。
There's an example app showing how this is done.有一个示例应用程序显示了这是如何完成的。 The demo app can be downloaded at:
演示应用程序可以在以下位置下载:
https://github.com/JohannBlake/Jetmagic https://github.com/JohannBlake/Jetmagic
When you run the app, open up the navigation tray and select any navigation item.运行应用程序时,打开导航托盘并选择任何导航项。 On the screen that appears, click on the button labeled
Return value from another screen
.在出现的屏幕上,单击标有
Return value from another screen
的按钮。 This will take you to another screen where you select an item and return to the previous screen.这将带您进入另一个屏幕,您可以在其中选择一个项目并返回上一个屏幕。 The selected item will be shown in a snackbar.
所选项目将显示在小吃店中。 This snackbar is global throughout the app.
这个小吃店在整个应用程序中都是全球性的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.