Set Dark & Light Themes in Jetpack Compose with RRutors
Jetpack Compose - Set styles for dark and light themes. Learn how to implement dynamic theming, custom styling, and adaptive UI with Jetpack Compose | RRTutors
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") }
)
})
}
)
}
|
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
|
|
|
|
|
|
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


