Skip to content

Instantly share code, notes, and snippets.

@kishan-vadoliya
Created October 19, 2023 05:11
Show Gist options
  • Save kishan-vadoliya/b55c3a70ce31104db7f5707fe1877cff to your computer and use it in GitHub Desktop.
Save kishan-vadoliya/b55c3a70ce31104db7f5707fe1877cff to your computer and use it in GitHub Desktop.
Multi theme in jetpack compose
// # Dark and light theme
// 01- Color
val colorBlue = Color(0xFF001E63)
val colorBlue1 = Color(0xFF000063)
val colorRed = Color(0xFF5A0000)
val colorGreen = Color(0xFF003A00)
val colorWhite = Color(0xFFFFFFFF)
val colorBlack = Color(0xE9000000)
// 02- Color Scheme
private val DarkColorScheme = darkColorScheme(
primary = colorBlue,
secondary = colorBlue1,
background = colorBlack,
onPrimary = colorWhite,
onSecondary = colorWhite,
onBackground = colorWhite
)
private val LightColorScheme = lightColorScheme(
primary = colorRed,
secondary = colorBlue1,
background = colorWhite,
onPrimary = colorWhite,
onSecondary = colorWhite,
onBackground = colorBlack
)
// 03- Enum Theme
enum class AppTheme {
Light, Dark, Default
}
// 04- Theme
@Composable
fun MyApplicationTheme(
appTheme: AppTheme,
isDarkMode: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = when (appTheme) {
AppTheme.Default -> {
if (isDarkMode) {
DarkColorScheme
} else {
LightColorScheme
}
}
AppTheme.Light -> {
LightColorScheme
}
AppTheme.Dark -> {
DarkColorScheme
}
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
// 05- Change theme programmatically
class MainViewModel: ViewModel() {
var stateApp by mutableStateOf(MainState())
fun onEvent(event: MainEvent) {
when(event) {
is MainEvent.ThemeChange -> {
stateApp = stateApp.copy(theme = event.theme)
}
}
}
}
sealed class MainEvent {
data class ThemeChange(val theme: AppTheme): MainEvent()
}
data class MainState(
val theme: AppTheme = AppPreferences.getTheme(),
)
// MainActivity
class MainActivity : ComponentActivity() {
val viewModel: MainViewModel = MainViewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme(appTheme = viewModel.stateApp.theme) {
HomeScreen(viewModel)
}
}
}
}
// Call event change theme
//Default
AppPreferences.setTheme(AppTheme.Default)
mainViewModel.onEvent(MainEvent.ThemeChange(AppTheme.Default))
//Light
AppPreferences.setTheme(AppTheme.Light)
mainViewModel.onEvent(MainEvent.ThemeChange(AppTheme.Light))
//Dark
AppPreferences.setTheme(AppTheme.Dark)
mainViewModel.onEvent(MainEvent.ThemeChange(AppTheme.Dark))
// Save theme using pref
object AppPreferences {
const val APP_THEME = "AppTheme"
fun setTheme(theme: AppTheme) {
Paper.book().write(APP_THEME, theme)
}
fun getTheme(): AppTheme {
return Paper.book().read(APP_THEME, AppTheme.Default)!!
}
}
// 01- Color
val colorBlue = Color(0xFF001E63)
val colorBlue1 = Color(0xFF000063)
val colorRed = Color(0xFF5A0000)
val colorGreen = Color(0xFF003A00)
val colorWhite = Color(0xFFFFFFFF)
val colorBlack = Color(0xE9000000)
// 02- Color Scheme
private val BlueColorScheme = lightColorScheme(
primary = colorBlue,
secondary = colorBlue1,
background = colorWhite,
onPrimary = colorWhite,
onSecondary = colorWhite,
onBackground = colorBlack
)
private val RedColorScheme = lightColorScheme(
primary = colorRed,
secondary = colorBlue1,
background = colorWhite,
onPrimary = colorWhite,
onSecondary = colorWhite,
onBackground = colorBlack
)
private val GreenColorScheme = lightColorScheme(
primary = colorGreen,
secondary = colorBlue1,
background = colorWhite,
onPrimary = colorWhite,
onSecondary = colorWhite,
onBackground = colorBlack
)
// 03- Enum Theme
enum class AppTheme {
Blue, Red, Green
}
// 04- Theme
@Composable
fun MyApplicationTheme(
appTheme: AppTheme,
isDarkMode: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = when (appTheme) {
AppTheme.Blue -> {
BlueColorScheme
}
AppTheme.Red -> {
RedColorScheme
}
AppTheme.Green -> {
GreenColorScheme
}
}
val systemUiController = rememberSystemUiController()
SideEffect {
systemUiController.setStatusBarColor(
color = colorScheme.primary,
darkIcons = false,
)
}
MaterialTheme(
colorScheme = colorScheme, typography = Typography, content = content
)
}
// 05- Change theme programmatically
ViewModel
class MainViewModel: ViewModel() {
}
// MainActivity
class MainViewModel: ViewModel() {
var stateApp by mutableStateOf(MainState())
fun onEvent(event: MainEvent) {
when(event) {
is MainEvent.ThemeChange -> {
stateApp = stateApp.copy(theme = event.theme)
}
}
}
}
sealed class MainEvent {
data class ThemeChange(val theme: AppTheme): MainEvent()
}
data class MainState(
val theme: AppTheme = AppPreferences.getTheme(),
)
val viewModel: MainViewModel = MainViewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme(appTheme = viewModel.stateApp.theme) {
HomeScreen(viewModel)
}
}
}
}
// Call event change theme
//Default
AppPreferences.setTheme(AppTheme.Blue)
mainViewModel.onEvent(MainEvent.ThemeChange(AppTheme.Blue))
//Red
AppPreferences.setTheme(AppTheme.Red)
mainViewModel.onEvent(MainEvent.ThemeChange(AppTheme.Red))
//Default
AppPreferences.setTheme(AppTheme.Green)
mainViewModel.onEvent(MainEvent.ThemeChange(AppTheme.Green))
// Save theme using pref
object AppPreferences {
const val APP_THEME = "AppTheme"
fun setTheme(theme: AppTheme) {
Paper.book().write(APP_THEME, theme)
}
fun getTheme(): AppTheme {
return Paper.book().read(APP_THEME, AppTheme.Blue)!!
}
}
// # Finally
// In theme.xml add this line for don’t force night mode on Android 10 devices and above
<style name="Theme.MultiTheme" parent="android:Theme.Material.Light.NoActionBar" >
<item name="android:forceDarkAllowed" tools:targetApi="q">false</item>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment