在 Composable 函数之外引用或枚举 Jetpack Compose MaterialTheme 主题颜色

发布于 2025-01-17 11:32:33 字数 1068 浏览 3 评论 0 原文

我希望为接受颜色的@composable函数提供一个参数,但只有一个来自离散列表的参数。

沿着这一行的内容:

enum class SpecialColor(val color: Color) {
    ALPHA(MaterialTheme.colors.onSurface),
    BETA(MaterialTheme.colors.onSecondary)
}

@Composable
fun ColorSample(specialColor: SpecialColor) {
    Box(
        modifier = Modifier
            .width(100.dp)
            .height(100.dp)
            .background(specialColor.color)
    )
}

@Preview
@Composable
fun PreviewSample() {
    CustomTheme {
        ColorSample(specialColor = SpecialColor.ALPHA)
    }
}

如上所述,引用了物质theme.colors.colors 在可综合上下文之外,发生以下错误:

@composable Invocations只能从一个上下文中发生 @composable功能

如果直接引用颜色而不是通过材料来引用颜色,则该颜色无法正确更新光/暗模式之类的内容。

一种策略可能是将枚举值映射到@composable函数本身中的材料颜色。但这很麻烦,笨重且不能很好地扩展 - 想象一下颜色的更长列表,并且希望重复使用许多功能的特色颜色列表。

另一种策略可能是用LocalContentColor或类似的方式直接修改主题颜色,但这太宽了刷子,不仅会更改颜色,而不仅仅是目标功能。

从实用程序@composable函数返回颜色也不是一个选项,因为@composable函数没有返回值。

所以...
关于如何提供列出的材料颜色列表之一作为参数的任何想法?
以干净且可扩展的方式可以很好地缩放?

I wish to provide a parameter to a @Composable function that accepts a color, but only one from a discrete list.

Something along the lines of this:

enum class SpecialColor(val color: Color) {
    ALPHA(MaterialTheme.colors.onSurface),
    BETA(MaterialTheme.colors.onSecondary)
}

@Composable
fun ColorSample(specialColor: SpecialColor) {
    Box(
        modifier = Modifier
            .width(100.dp)
            .height(100.dp)
            .background(specialColor.color)
    )
}

@Preview
@Composable
fun PreviewSample() {
    CustomTheme {
        ColorSample(specialColor = SpecialColor.ALPHA)
    }
}

As the above is referencing MaterialTheme.colors outside a composable context, the following error occurs:

@Composable invocations can only happen from the context of a
@Composable function

If a color is referenced directly, instead of via MaterialTheme, the color won't properly update for things like light/dark mode.

One tactic might be to map enumerated values to MaterialTheme colors within the @Composable function itself. But this is cumbersome, bulky, and doesn't scale well - imagine a much longer list of colors and the same SpecialColor list desired to be reused for many function.

Another tactic might be to modify the theme colors directly with LocalContentColor or similar, but this is too broad of a brush and will change colors for more than just the targeted function.

Returning a color from a utility @Composable function is also not an option, as @Composable functions don't have return values.

So...

Any thoughts on how to provide one of an enumerated list of Compose Material colors as a parameter?

In a clean and extendable way that scales well?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦罢 2025-01-24 11:32:33

这实际上是不正确的:

@Composable 函数没有返回值。

您可以使用返回类型注释这两个函数,甚至可以使用 @Composable 注释仅 getter 属性。例如 是的一部分材质主题源代码。

以下是定义颜色的方法:

enum class SpecialColor {
    ALPHA,
    BETA,
    ;

    val color: Color
        @Composable
        @ReadOnlyComposable
        get() = when(this) {
            ALPHA -> MaterialTheme.colors.onSurface
            BETA -> MaterialTheme.colors.onSecondary
        }
}

This is actually not true:

@Composable functions don't have return values.

You can annotate both function with return types and even getter only properties with @Composable. For example this is part of Material theme source code.

Here's how you can define your color:

enum class SpecialColor {
    ALPHA,
    BETA,
    ;

    val color: Color
        @Composable
        @ReadOnlyComposable
        get() = when(this) {
            ALPHA -> MaterialTheme.colors.onSurface
            BETA -> MaterialTheme.colors.onSecondary
        }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文