Compose material design themes, How to set dark and Light theme with jetpack compose?

Last updated Sep 15, 2021


In this Jetpack compose material tutorial we will learn How to set dark and Light theme with jetpack compose in Android application. 

 

Let's get started

Step 1: Create android application in android studio

Step 2: Follow step for setup Jetpack Compose with Android Studio

Add 3 options for Dark,Light and System theme

object ThemeMode {
const val Dark = "Dark"
const val Light = "Light"
const val System = "System"
}

 

 

Add data class ThemeData with title and value

data class ThemeData(
    val title: String,
    val value: Boolean
)

 

 

where title will be ThemeMode and value will be true or false depending upon dark and light theme 

Let's add a ThemeDemo composable function where we are going to add all the logic of ui

@Composable
fun ThemeDemo(){
    //here we are going to add the ui logic 
}

 

 

We are going to use remember composable to store the selected theme

val mode = remember { mutableStateOf(ThemeData(ThemeMode.Light, false)) }

 

 

We have added initial theme as a Light theme.

Add Color.kt

package com.example.jetpack.ui.theme

import androidx.compose.ui.graphics.Color

    val BackgroundColorForLight = Color(0xFFFFFFFF)
    val BackgroundColorForDark = Color(0xFF000000)
    val SurfaceColorForLight = Color(0xFFFFFFFF)
    val SurfaceColorForDark = Color(0xEE000000)
    val SecondaryColorForLight = Color(0xFF3d8c31)
    val SecondaryColorForDark = Color(0xFF50a03b)
    val BlackColor = Color(0xFF000000)
    val WhiteColor = Color(0xFFFFFFFF)
    val PrimaryColor = Color(0xFF3d0482)
    val PrimaryVariantColor = Color(0xFF6f0c97)
    val OnBackgroundColor = Color(0xFF7b7b7b)
    val ErrorColor=Color(0xFFed2b2b)

 

 

Add Theme.kt where we are going to define light and dark theme colors

package com.example.jetpack.ui.theme

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable

val light = lightColors(
        primary = PrimaryColor,
        primaryVariant = PrimaryVariantColor,
        secondary = SecondaryColorForLight,
        secondaryVariant = SecondaryColorForLight,
        background = BackgroundColorForLight,
        surface = SurfaceColorForLight,
        error = ErrorColor,
        onPrimary = WhiteColor,
        onSecondary = WhiteColor,
        onBackground = BlackColor,
        onSurface = BlackColor,
        onError = ErrorColor
        )
        val dark = darkColors(
        background = BackgroundColorForDark,
        surface = SurfaceColorForDark,
        primary = PrimaryColor,
        secondary = SecondaryColorForDark,
        onBackground = OnBackgroundColor,
        onSurface = WhiteColor,
        onPrimary = WhiteColor,
        onSecondary = WhiteColor,
        primaryVariant = PrimaryVariantColor,
        secondaryVariant = SecondaryColorForDark,
        onError = ErrorColor,
        error = ErrorColor,
        )

@Composable
fun JetPackTheme(
        darkTheme: Boolean = isSystemInDarkTheme(),
        content: @Composable() () -> Unit
        ) {
        MaterialTheme(
        colors = if (darkTheme) dark else light,
        typography = Typography,
        shapes = Shapes,
        content = content
        )
        }

 

 

Add color in color.xml file

    #FFFFFFFF
    #FF000000
    #FFFFFFFF
    #EE000000
    #FF3d8c31
    #FF50a03b
    #FF3d0482
    #FF6f0c97
    #FF7b7b7b
    #FFed2b2b
    #FF000000
    #FFFFFFFF

 

Let's wrap the ui code with JetPackTheme

@Composable
fun ThemeDemo(
        ) {
        val mode = remember { mutableStateOf(ThemeData(ThemeMode.Light, false)) }
        JetPackTheme(
        darkTheme = mode.value.value,
        content = {
        val value = isSystemInDarkTheme()
        Scaffold(content = {
        Column(content = {
        Row {
        RadioButton(
        selected = mode.value.title == ThemeMode.Dark,
        onClick = {
        mode.value = ThemeData(ThemeMode.Dark, true)
        })
        Spacer(modifier = Modifier.size(16.dp))
        Text(
        ThemeMode.Dark,
        color = MaterialTheme.colors.onBackground,
        fontWeight = FontWeight.Bold
        )
        Spacer(modifier = Modifier.size(16.dp))
        RadioButton(
        selected = mode.value.title == ThemeMode.Light,
        onClick = {
        mode.value = ThemeData(ThemeMode.Light, false)
        })
        Spacer(modifier = Modifier.size(16.dp))
        Text(
        ThemeMode.Light,
        color = MaterialTheme.colors.onBackground,
        fontWeight = FontWeight.Bold
        )
        Spacer(modifier = Modifier.size(16.dp))
        RadioButton(
        selected = mode.value.title == ThemeMode.System,
        onClick = {
        mode.value = ThemeData(ThemeMode.System, value)
        })
        Spacer(modifier = Modifier.size(16.dp))
        Text(
        ThemeMode.System,
        color = MaterialTheme.colors.onBackground,
        fontWeight = FontWeight.Bold
        )
        }
        Spacer(modifier = Modifier.size(16.dp))
        Card(
        content = {
        Column(content = {
        Text("Card with dark and light theme")
        }, modifier = Modifier.padding(16.dp))
        }, modifier = Modifier.fillMaxWidth()
        )
        val name = "Abhishek"
        val gender = "Male"
        val emailId = "Abcded@gmail.com"
        Spacer(modifier = Modifier.size(16.dp))
        Card(modifier = Modifier
        .fillMaxWidth(), content = {
        Row(Modifier
        .padding(16.dp),
        content = {
        val color =
        Color.Red
        Box(
        content = {
        Text(
        text = name[0].uppercase(),
        fontSize = 24.sp
        )
        }, modifier = Modifier
        .size(80.dp)
        .border(
        width = 1.2.dp,
        color = color,
        shape = CircleShape
        ),
        contentAlignment = Alignment.Center
        )
        Spacer(modifier = Modifier.size(16.dp))
        Column(
        modifier = Modifier.weight(2F),
        content = {
        Spacer(modifier = Modifier.size(8.dp))
        Text(
        text = name.uppercase(),
        fontSize = 16.sp,
        maxLines = 1,
        overflow = TextOverflow.Ellipsis
        )
        Text(
        text = gender,
        fontSize = 14.6.sp
        )
        Text(
        text = emailId,
        maxLines = 1,
        overflow = TextOverflow.Ellipsis
        )
        })

        })
        })

        }, modifier = Modifier.padding(16.dp))
        }, topBar = {
        TopAppBar(
        title = { Text("Theme Demo") }
        )
        })
        }
        )
        }

 

 

Download Source code

 

 

Full Code

package com.example.jetpack

import android.os.Bundle
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.border
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.jetpack.ui.theme.JetPackTheme

class MainActivity : ComponentActivity() {

        override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
        setContent {
        ThemeDemo()
        }
        }
        }

        data class ThemeData(
        val title: String,
        val value: Boolean
        )

        object ThemeMode {
        const val Dark = "Dark"
        const val Light = "Light"
        const val System = "System"
        }

@Composable
fun ThemeDemo(
        ) {
        val mode = remember { mutableStateOf(ThemeData(ThemeMode.Light, false)) }
        JetPackTheme(
        darkTheme = mode.value.value,
        content = {
        val value = isSystemInDarkTheme()
        Scaffold(content = {
        Column(content = {
        Row {
        RadioButton(
        selected = mode.value.title == ThemeMode.Dark,
        onClick = {
        mode.value = ThemeData(ThemeMode.Dark, true)
        })
        Spacer(modifier = Modifier.size(16.dp))
        Text(
        ThemeMode.Dark,
        color = MaterialTheme.colors.onBackground,
        fontWeight = FontWeight.Bold
        )
        Spacer(modifier = Modifier.size(16.dp))
        RadioButton(
        selected = mode.value.title == ThemeMode.Light,
        onClick = {
        mode.value = ThemeData(ThemeMode.Light, false)
        })
        Spacer(modifier = Modifier.size(16.dp))
        Text(
        ThemeMode.Light,
        color = MaterialTheme.colors.onBackground,
        fontWeight = FontWeight.Bold
        )
        Spacer(modifier = Modifier.size(16.dp))
        RadioButton(
        selected = mode.value.title == ThemeMode.System,
        onClick = {
        mode.value = ThemeData(ThemeMode.System, value)
        })
        Spacer(modifier = Modifier.size(16.dp))
        Text(
        ThemeMode.System,
        color = MaterialTheme.colors.onBackground,
        fontWeight = FontWeight.Bold
        )
        }
        Spacer(modifier = Modifier.size(16.dp))
        Card(
        content = {
        Column(content = {
        Text("Card with dark and light theme")
        }, modifier = Modifier.padding(16.dp))
        }, modifier = Modifier.fillMaxWidth()
        )
        val name = "Abhishek"
        val gender = "Male"
        val emailId = "Abcded@gmail.com"
        Spacer(modifier = Modifier.size(16.dp))
        Card(modifier = Modifier
        .fillMaxWidth(), content = {
        Row(Modifier
        .padding(16.dp),
        content = {
        val color =
        Color.Red
        Box(
        content = {
        Text(
        text = name[0].uppercase(),
        fontSize = 24.sp
        )
        }, modifier = Modifier
        .size(80.dp)
        .border(
        width = 1.2.dp,
        color = color,
        shape = CircleShape
        ),
        contentAlignment = Alignment.Center
        )
        Spacer(modifier = Modifier.size(16.dp))
        Column(
        modifier = Modifier.weight(2F),
        content = {
        Spacer(modifier = Modifier.size(8.dp))
        Text(
        text = name.uppercase(),
        fontSize = 16.sp,
        maxLines = 1,
        overflow = TextOverflow.Ellipsis
        )
        Text(
        text = gender,
        fontSize = 14.6.sp
        )
        Text(
        text = emailId,
        maxLines = 1,
        overflow = TextOverflow.Ellipsis
        )
        })

        })
        })

        }, modifier = Modifier.padding(16.dp))
        }, topBar = {
        TopAppBar(
        title = { Text("Theme Demo") }
        )
        })
        }
        )
        }





@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
        ThemeDemo()
        }

 

 

Image

Jetpack Compose Set Material Themes

Jetpack Compose Set Material Dark Themes

Jetpack Compose Set Material Light Themes

Conclusion: In this compose tutorial we covered how to set theme for android application, set custom dark theme and light theme by Jetpack compose material.

 

Compose Examples:

Create Navigation Drawer with Jetpack compose

Jetpack Compose Webview example - Load Webpages with Compose

Create Toast with Jetpack Compose

Create Room Database with Jetpack Compose

 

 


Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

66 Views

Subscribe For Daily Updates

Flutter Questions
Android Questions