Ссылка или перечисление цветов темы Jetpack Compose MaterialTheme вне функции Composable

Я хочу предоставить параметр функции @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)
    }
}

Поскольку приведенное выше относится к MaterialTheme.colors вне компонуемого контекста, возникает следующая ошибка:

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

Если на цвет ссылаются напрямую, а не через MaterialTheme, цвет не будет правильно обновляться для таких вещей, как светлый/темный режим.

Одной из тактик может быть сопоставление перечисляемых значений с цветами MaterialTheme внутри самой функции @Composable. Но это громоздко, громоздко и плохо масштабируется — представьте себе гораздо более длинный список цветов и тот же список SpecialColor, который нужно повторно использовать для многих функций.

Другая тактика может заключаться в изменении цветов темы напрямую с помощью LocalContentColor или аналогичного, но это слишком широкая кисть и изменит цвета не только для целевой функции.

Возврат цвета из служебной функции @Composable также невозможен, поскольку функции @Composable не имеют возвращаемых значений.

Итак...
Любые мысли о том, как предоставить один из перечисленного списка цветов Compose Material в качестве параметра?
Чистым и расширяемым способом, который хорошо масштабируется?

4
0
103
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На самом деле это не так:

@Composable functions don't have return values.

Вы можете аннотировать обе функции с возвращаемыми типами и даже получать только свойства с помощью @Composable. Например, это является частью исходного кода темы Material.

Вот как вы можете определить свой цвет:

enum class SpecialColor {
    ALPHA,
    BETA,
    ;

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

Другие вопросы по теме