Как управлять темой и стилями в Jetpack Compose

Основные концепции тем и стилей в Jetpack Compose

  1. Тема (Theme): В Jetpack Compose тема определяет общий внешний вид вашего приложения, включая цвета, типографику, формы компонентов и другие параметры. Тема создается на основе MaterialTheme, который предоставляет все необходимые элементы для соответствия Material Design.

  2. Цветовая палитра (Color): Ваша тема включает в себя цветовую палитру, которая управляет цветами, используемыми в приложении.

  3. Типографика (Typography): Определяет набор шрифтов, их стили и размеры.

  4. Форма (Shapes): Указывает на формы, которые будут применяться к элементам интерфейса, таким как кнопки, карточки и т.д.

Создание и настройка темы

Для создания темы в Jetpack Compose вы обычно создаете файл с темой, который будет содержать определение вашей темы. Стандартный шаблон включает в себя базовую структуру, которую вы можете настраивать под свои нужды.

private val LightColorScheme = lightColorScheme(  
    primary = md_theme_light_primary,  
    onPrimary = md_theme_light_onPrimary,  
    primaryContainer = md_theme_light_primaryContainer,  
    onPrimaryContainer = md_theme_light_onPrimaryContainer,  
    secondary = md_theme_light_secondary,  
    onSecondary = md_theme_light_onSecondary,  
    secondaryContainer = md_theme_light_secondaryContainer,  
    onSecondaryContainer = md_theme_light_onSecondaryContainer,  
    tertiary = md_theme_light_tertiary,  
    onTertiary = md_theme_light_onTertiary,  
    tertiaryContainer = md_theme_light_tertiaryContainer,  
    onTertiaryContainer = md_theme_light_onTertiaryContainer,  
    error = md_theme_light_error,  
    onError = md_theme_light_onError,  
    errorContainer = md_theme_light_errorContainer,  
    onErrorContainer = md_theme_light_onErrorContainer,  
    outline = md_theme_light_outline,  
    background = md_theme_light_background,  
    onBackground = md_theme_light_onBackground,  
    surface = md_theme_light_surface,  
    onSurface = md_theme_light_onSurface,  
    surfaceVariant = md_theme_light_surfaceVariant,  
    onSurfaceVariant = md_theme_light_onSurfaceVariant,  
    inverseSurface = md_theme_light_inverseSurface,  
    inverseOnSurface = md_theme_light_inverseOnSurface,  
    inversePrimary = md_theme_light_inversePrimary,  
    surfaceTint = md_theme_light_surfaceTint,  
    outlineVariant = md_theme_light_outlineVariant,  
    scrim = md_theme_light_scrim,  
)

private val DarkColorScheme = darkColorScheme(  
    primary = md_theme_dark_primary,  
    onPrimary = md_theme_dark_onPrimary,  
    primaryContainer = md_theme_dark_primaryContainer,  
    onPrimaryContainer = md_theme_dark_onPrimaryContainer,  
    secondary = md_theme_dark_secondary,  
    onSecondary = md_theme_dark_onSecondary,  
    secondaryContainer = md_theme_dark_secondaryContainer,  
    onSecondaryContainer = md_theme_dark_onSecondaryContainer,  
    tertiary = md_theme_dark_tertiary,  
    onTertiary = md_theme_dark_onTertiary,  
    tertiaryContainer = md_theme_dark_tertiaryContainer,  
    onTertiaryContainer = md_theme_dark_onTertiaryContainer,  
    error = md_theme_dark_error,  
    onError = md_theme_dark_onError,  
    errorContainer = md_theme_dark_errorContainer,  
    onErrorContainer = md_theme_dark_onErrorContainer,  
    outline = md_theme_dark_outline,  
    background = md_theme_dark_background,  
    onBackground = md_theme_dark_onBackground,  
    surface = md_theme_dark_surface,  
    onSurface = md_theme_dark_onSurface,  
    surfaceVariant = md_theme_dark_surfaceVariant,  
    onSurfaceVariant = md_theme_dark_onSurfaceVariant,  
    inverseSurface = md_theme_dark_inverseSurface,  
    inverseOnSurface = md_theme_dark_inverseOnSurface,  
    inversePrimary = md_theme_dark_inversePrimary,  
    surfaceTint = md_theme_dark_surfaceTint,  
    outlineVariant = md_theme_dark_outlineVariant,  
    scrim = md_theme_dark_scrim,  
)

@Composable  
fun AppTheme(  
    darkTheme: Boolean = isSystemInDarkTheme(),  
    // Dynamic color is available on Android 12+  
    dynamicColor: Boolean = true,  
    content: @Composable () -> Unit  
) {  
    val colorScheme = when {  
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {  
            val context = LocalContext.current  
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)  
        }  
  
        darkTheme -> LightColorScheme  
        else -> LightColorScheme  
    }  
    val view = LocalView.current  
    if (!view.isInEditMode) {  
        SideEffect {  
            val window = (view.context as Activity).window  
            val transparentColor = ContextCompat.getColor(view.context, android.R.color.transparent)  
  
            window.statusBarColor = transparentColor  
            window.navigationBarColor = transparentColor  
            window.statusBarColor = colorScheme.primary.toArgb()  
            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = true  
            window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)  
        }  
    }  
  
    MaterialTheme(  
        colorScheme = colorScheme,  
        typography = Typography,  
        content = content  
    )  
}


Здесь создаются две цветовые палитры: одна для темной темы и одна для светлой. Затем выбирается одна из них в зависимости от параметра darkTheme. MaterialTheme используется для настройки темы приложения с использованием выбранной цветовой палитры, типографики и форм.