Theming in Jetpack Compose application

What is rememberSystemUiController()?

How do you theme an app in jetpack compose?

The theme is set at the top level of setContent()


// code to set the theme 
@AndroidEntryPoint
class ScaffoldActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            NationalParksTheme {
                NationalParksApp()
            }
        }
    }
}

How do you define light and dark mode in jetpack compose?

In Theme.kt file, you would define your dark and light theme?


private val LightColors = lightColorScheme(
    primary = md_theme_light_primary,
    onPrimary = md_theme_light_onPrimary,
    primaryContainer = md_theme_light_primaryContainer,
    onPrimaryContainer = md_theme_light_onPrimaryContainer,
    ...
)

private val DarkColors = darkColorScheme(
    primary = md_theme_dark_primary,
    onPrimary = md_theme_dark_onPrimary,
    primaryContainer = md_theme_dark_primaryContainer,
    onPrimaryContainer = md_theme_dark_onPrimaryContainer,
    ...
)

And you would use it in your theme definition


 MaterialTheme(
        colorScheme = colorScheme,
        shapes = Shapes,
        typography = Typography,
        content = content
    )

The full code for figuring out the colorScheme, shapes, typography and content are


  val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
        }

        darkTheme -> DarkColors
        else -> LightColors
    }
    val view = LocalView.current
    if (!view.isInEditMode) {
        val systemUiController = rememberSystemUiController()
        val useDarkIcons = !isSystemInDarkTheme()
        val window = (view.context as Activity).window
        WindowCompat.setDecorFitsSystemWindows(window, false)
        DisposableEffect(systemUiController, useDarkIcons) {
            // Update all of the system bar colors to be transparent, and use
            // dark icons if we're in light theme
            systemUiController.setSystemBarsColor(
                color = Color.Transparent,
                darkIcons = useDarkIcons
            )
            onDispose {}
        }
    }
    
	MaterialTheme(
	        colorScheme = colorScheme,
	        shapes = Shapes,
	        typography = Typography,
	        content = content
	    )

In here, it has the logic to handle the dynamicColorTheme, which is a way to using colors based on theme

How do you set light and dark mode in jetpack compose theme?

The setting of light, dark and dynamic theming happens here


val colorScheme = when {
        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
            val context = LocalContext.current
            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
        }

        darkTheme -> DarkColors
        else -> LightColors
    }

How do you define the typography in jetpack compose?


val Typography = Typography(
    displaySmall = TextStyle(
        fontWeight = FontWeight.Normal,
        fontSize = 36.sp
    ),
    headlineSmall = TextStyle(
        fontWeight = FontWeight.Normal,
        fontSize = 30.sp
    ),
    labelSmall = TextStyle(
        fontWeight = FontWeight.Normal,
        fontSize = 13.sp
    ),
    titleSmall = TextStyle(
        fontWeight = FontWeight.Bold,
        fontSize = 14.sp
    ),
    titleMedium = TextStyle(
        fontWeight = FontWeight.SemiBold,
        letterSpacing = (.5).sp,
        fontSize = 18.sp
    ),
    titleLarge = TextStyle(
        fontWeight = FontWeight.Normal,
        fontSize = 24.sp
    ),
)

And it's used as followed:


Text(
            text = name,
            style = MaterialTheme.typography.displaySmall,
            modifier = Modifier

What is shapes in MaterialTheme?

In Jetpack Compose, shapes within MaterialTheme refers to the visual appearance of surfaces and elements in your application, defining the corner roundness and overall form of UI components. It is part of the Material Design System and helps in creating visually appealing and consistent UIs.

The shapes parameter in MaterialTheme allows you to define a set of common shapes that can be reused throughout your application. These shapes can be applied to various UI components to give them a consistent look and feel. Here's what you need to know about shapes:


// An example of how to design Shapes in Jetpack Compose
val Shapes = Shapes(
    small = RoundedCornerShape(
        topStart = 0.dp,
        topEnd = 12.dp,
        bottomStart = 12.dp,
        bottomEnd = 0.dp
    ),
    medium = RoundedCornerShape(
        topStart = 0.dp,
        topEnd = 12.dp,
        bottomStart = 12.dp,
        bottomEnd = 0.dp
    )

// and you would use it as followed

FloatingActionButton(
        onClick = onFabClick,
        shape = MaterialTheme.shapes.small,
        // Semantics in parent due to https://issuetracker.google.com/184825850
        modifier = modifier.semantics {
            contentDescription = addPlantContentDescription
        }
    ) {
        Icon(
            Icons.Filled.Add,
            contentDescription = null
        )
    }

What is content in MaterialTheme?

content is likely a lambda function that defines the content to be displayed within the scope of the MaterialTheme.

In Jetpack Compose, MaterialTheme is used to apply a theme to a part of the UI hierarchy. It takes parameters for defining the color scheme, typography, and shapes, among other things. The content block is where you would place the UI elements that should be styled according to the theme defined in MaterialTheme.

Here's a general example of how MaterialTheme might be used with a content block:

Implement Custom Font in Jetpack Compose