android - Jetpack Compose 中未显示 Snackbar

标签 android android-jetpack-compose

我的屏幕有一个按钮,点击它,我想在短时间内显示一个 snackbar 。所以这是我的可组合:

@Composable
fun RegisterLocation(
    navController: NavController,
    locationVm: LocationViewModel = LocationViewModel()
) {
    val uiState = locationVm.locationState.collectAsState(LocationUiState.Init)
    val snackbarHostState = remember { SnackbarHostState() }
    when (uiState.value) {
        is LocationUiState.Init -> RegisterLocation(locationVm, snackbarHostState)
        is LocationUiState.Invalid -> {
            LaunchedEffect(locationVm.locationState.value) {
                snackbarHostState.showSnackbar(
                    "Failed Creating Location. Try Again!!!"
                )
            }
        }
        is LocationUiState.Valid -> navController.popBackStack()
    }
}

@Composable
fun RegisterLocation(locationVm: WLocationViewModel, snackbarHostState: SnackbarHostState) {
    Box(Modifier.fillMaxSize()) {
        Column {
            SubmitLocation(locationVm)
        }

        Column(
            Modifier
                .fillMaxWidth()
                .align(Alignment.BottomCenter)
        ) {
            Text(text = "Hello") // <-- This is a dummy text and it shows in the UI. Moreover, it animates up to give space for snackbar. But the snackbar doesn't show up :(
            RegistrationError(snackbarHostState)
        }
    }
}

@ExperimentalCoroutinesApi
@Composable
fun SubmitLocation(vm: WLocationViewModel) {
    Button(
        onClick = { vm.onCreate(LocationUiState.Invalid) },
        modifier = Modifier.fillMaxWidth()
    ) {
        Text(text = "Submit Location")
    }
}

@Composable
fun RegistrationError(hostState: SnackbarHostState) {
    SnackbarHost(
        hostState = hostState,
        modifier = Modifier.fillMaxWidth(),
        snackbar = {
            Snackbar {
                Text(text = "Hello", color = Color.White)
            }
        }
    )
}
这段代码有什么问题?任何帮助,将不胜感激。

最佳答案

SnackbarHostState显示 snackbarScaffold或者可以作为参数传递给 SnackBar可组合的。

Why the snackbar host does not show the snackbar ?


每当state改变了snackBar 所做的不是 有任何ScaffoldSnackbarHost显示内容。 (snackbarHostState 也可以在组成你已经完成的 SnackBar 时传递 - 检查解决方案 2 )
您既没有使用 Scaffold也不构成 SnackBarHost通过使用 snackBarHostState期间无效 状态。
解决方案一
我们需要附上 SnackbarHostStateScaffold让它出现。
when (uiState.value) {
   is LocationUiState.Init -> RegisterLocation(locationVm, snackbarHostState)
   is LocationUiState.Invalid -> {
         LaunchedEffect(locationVm.locationState.value) {
            snackbarHostState.showSnackbar(
                    "Failed Creating Location. Try Again!!!",
                    "label",
                    duration = SnackbarDuration.Long
            )
         }
         Scaffold(
                // attach snackbar host state to the scaffold
             scaffoldState = rememberScaffoldState(snackbarHostState = snackbarHostState),
             content = { } // content is not mandatory
         )
   }
}
1
解决方案二 :-
你永远不会作曲RegisterLocation(locationVm, snackbarHostState)处于无效状态。根据代码,如果我们编写 RegisterLocation在 Invalid 状态下可组合,然后应显示作为可组​​合添加的 snackbar 。
when (uiState.value) {
        is LocationUiState.Init -> RegisterLocation(locationVm, snackbarHostState)
        is LocationUiState.Invalid -> {
            RegistrationError(hostState = snackbarHostState)
            LaunchedEffect(locationVm.locationState.value) {
                snackbarHostState.showSnackbar(
                    "Failed Creating Location. Try Again!!!",
                    "label",
                    duration = SnackbarDuration.Long
                )
            }
        }
}
更新 ( 详细说明 )
Compose 维护一个 GroupArray under the hood ,其中包含根据其位置在屏幕中绘制的所有 UI 元素。因此,在重新组合期间,它仅比较并显示在重新组合期间绘制的 UI 元素,并删除在先前组合期间构建的其他组件,即 redundant。 (如在重新组合期间我们不访问的 UI 组件被删除)。
对于您的情况:- states完全不同,我们从不访问Init 期间的状态第二作品。因此,compose 在重新组合期间看到我们从未访问过 Init状态,因此它会删除 Init内存中的 UI。
(使用 positional memoisation 在引擎盖下)。
请查看compose under the hood

关于android - Jetpack Compose 中未显示 Snackbar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67539655/

相关文章:

android - 如何在程序运行时更改布局参数

Android NDK revision 7 Host 'awk' tool is outdated 错误

android - 如何更新项目中的 Jetpack Compose 版本?

android - android jetpack compose中的 "remember"和 "mutableState"有什么区别?

android - Android Compose 生产准备好了吗?

安卓撰写。尝试运行基本代码时出错

android - 使用 Jetpack Compose 在单击按钮时动态添加 View

Android:基于位置的应用程序

java - 从启动画面切换到 MainActivity 时应用程序崩溃

android - 如何在 map 中为谷歌默认图标放置我自己的图标?