Как сделать тему Jetpack Compose настраиваемой?

Я работаю над системой дизайна с Jetpack Compose, у меня есть много компонентов, использующих мою тему для доступа к цветам, типографике и размерам. Сейчас рассматриваю возможность настройки. Например, переопределение цвета приводит к его изменению для каждого компонента.

До сих пор я пытался добавить параметры в забавную MyTheme. У меня был некоторый успех с этим подходом, но проблема в том, что любой разработчик может изменить тему в любое время, как это. Я хотел бы, чтобы его можно было настроить только один раз, может быть, как синглтон. Любые идеи или рекомендации?

Вот моя тема:

private val LightColorPalette = LightColors()
private val DarkColorPalette = DarkColors()

private val LocalColors = compositionLocalOf<MyColors> {
    error("No typography provided! Make sure to wrap all usages of this components in a MyTheme.")
}

private val LocalTypography = compositionLocalOf<MyTypography> {
    error("No typography provided! Make sure to wrap all usages of this components in a MyTheme.")
}

private val LocalDimensions = staticCompositionLocalOf { MyDimensions() }

@Composable
fun MyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    colors: MyColors = if (darkTheme) DarkColorPalette else LightColorPalette,
    typography: MyTypography = getTypography(LocalConfiguration.current),
    dimensions: MyDimensions = getDimensions(LocalConfiguration.current),
    content: @Composable () -> Unit
) {
    val shapes = MaterialShapes

    CompositionLocalProvider(
        LocalTypography provides typography,
        LocalColors provides colors,
        LocalDimensions provides dimensions,
    ) {
        MaterialTheme(
            colors = debugColors(darkTheme),
            content = content,
            shapes = shapes
        )
    }
}

Я считаю, что следующая документация страница говорит именно об этом.

Arthur Kasparian 20.11.2022 22:37
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Можете ли вы объяснить разницу между ngOnInit и конструктором в Angular?
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
0
1
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Мне удалось заставить это работать, сделав все мои переменные CompositionLocal общедоступными. При этом любая новая тема, которая переопределяет эти переменные с помощью CompositionLocalProvider, будет иметь под собой составные объекты, использующие эти новые значения.

@Composable
fun SecondaryTheme(
    content: @Composable () -> Unit
) {
    val configuration = LocalConfiguration.current

    val colors = SecondaryColors()
    val typography = getDefaultTypography(configuration)
    val dimensions = getDefaultDimensions(configuration)
    val shapes = MaterialShapes

    CompositionLocalProvider(
        LocalTypography provides typography,
        LocalColors provides colors,
        LocalDimensions provides dimensions,
    ) {
        MaterialTheme(
            colors = materialColors(darkTheme),
            content = content,
            shapes = shapes
        )
    }
}

Рекомендую ознакомиться с официальной документацией

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