如何在自定义 TopAppBar 中不使用自定义颜色

How to not use a custom colour in a custom TopAppBar

在 cetrain 期间我想使用我自己的颜色资源 ColorGreen 来更改我的自定义 SmallTopAppBar 的背景颜色,而在其他时间我不想使用它所以根据设备的当前主题,使用默认的黑色和白色。避免可能的空指针异常的最佳方法是什么?是否应该在自定义工具栏代码中使用 'if null' 语句?下划线所在的 activity 声明中是否应使用 null

Color.kt

val ColorGreen = Color(0,110,20,255)

自定义工具栏代码

package com.mycompany.myapp.ui.components

import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign

@Composable
fun MySmallTopAppBar(
    backgroundColor: Color,
    title: String,
    titleColor: Color
) {
    SmallTopAppBar(
        colors = TopAppBarDefaults.smallTopAppBarColors(
            containerColor = backgroundColor),
        title = {
            Text(
                text = title,
                style = MaterialTheme.typography.titleMedium,
                textAlign = TextAlign.Start,
                maxLines = 1,
                color = titleColor
            )
        }
    )
}

在MainActivity.kt

...
    setContent {

        MyAppTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                Scaffold(
                    topBar = { MySmallTopAppBar(ColorGreen, getGreetingMessage(), __) }
                ) {
                }
            }
        }
    }
...

在这种情况下,您需要检查组件源代码以了解其工作原理。

Text 的情况下,默认颜色值为 Color.Unspecified - 如果使用此值,颜色将从样式或 LocalContentColor 中获取(样式值未指定也)。所以如果你想遵循默认行为,你也需要传递这个值:

val backgroundColor: Color?
// ...
MySmallTopAppBar(backgroundColor, getGreetingMessage(), if (backgroundColor == null) Color.Unspecified else Color.SomeColor)

如果 smallTopAppBarColors 默认值是内部的,再加上它可能会在未来改变(因为 material 3 目前处于 alpha 状态),最正确的方法是这样的:

colors = if (backgroundColor != null)
    TopAppBarDefaults.smallTopAppBarColors(containerColor = backgroundColor)
else
    TopAppBarDefaults.smallTopAppBarColors(),