Jetpack 撰写自定义零食栏材料 3

Rez*_*aji 8 kotlin android-jetpack-compose

如何使用材料3在compose中实现自定义snackbar?我想更改小吃栏的对齐方式。另外,我希望在左侧或右侧的小吃栏上显示动态图标。

Thr*_*ian 15

您可以使用 SnackBar 可组合项自定义您的小吃栏,并且可以使用 Box 内的 SnackbarHost 对齐方式更改对齐方式(如果您的意思是这样的话)。

val snackState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope()

Box(
    modifier = Modifier
        .fillMaxSize()
        .padding(20.dp)
) {

    Column(modifier = Modifier.fillMaxSize()) {
        Button(
            modifier = Modifier.fillMaxWidth(),
            onClick = {
                coroutineScope.launch {
                    snackState.showSnackbar("Custom Snackbar")
                }
            }) {
            Text("Show Snackbar")
        }
    }
    SnackbarHost(
        modifier=Modifier.align(Alignment.BottomStart),
        hostState = snackState
    ) { snackbarData: SnackbarData ->
        CustomSnackBar(
            R.drawable.baseline_swap_horiz_24,
            snackbarData.visuals.message,
            isRtl = true,
            containerColor = Color.Gray
        )
    }
}

@Composable
fun CustomSnackBar(
    @DrawableRes drawableRes: Int,
    message: String,
    isRtl: Boolean = true,
    containerColor: Color = Color.Black
) {
    Snackbar(containerColor = containerColor) {
        CompositionLocalProvider(
            LocalLayoutDirection provides
                    if (isRtl) LayoutDirection.Rtl else LayoutDirection.Ltr
        ) {
            Row {

                Icon(
                    painterResource(id = drawableRes),
                    contentDescription = null
                )
                Text(message)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Dam*_*enL 11

已验证的答案无法正确回答问题,因为图标是以静态方式提供的,而不是动态的。该图标不会传递到showSnackbar.

您可以通过拥有自己的来做到这一点SnackbarVisuals

// Your custom visuals
// Default values are the same than SnackbarHostState.showSnackbar
data class SnackbarVisualsCustom(
    override val message: String,
    override val actionLabel: String? = null,
    override val withDismissAction: Boolean = false,
    override val duration: SnackbarDuration = if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite
    // You can add custom things here (for you it's an icon)
    @DrawableRes val drawableRes: Int
) : SnackbarVisuals


// The way you decide how to display your custom visuals
SnackbarHost(hostState = snackbarHostState) {
    val customVisuals = it.visuals as SnackbarVisualsCustom
    Snackbar {
        // Here is your custom snackbar where you use your icon
    }
}

// To display the custom snackbar
snackbarHostStateScope.launch {
    snackbarHostState.showSnackbar(
        SnackbarVisualsCustom(
            message = "The message",
            drawableRes = R.drawable.your_icon_id
        )
    )
}
Run Code Online (Sandbox Code Playgroud)