[英]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.