Created
October 19, 2023 05:11
-
-
Save kishan-vadoliya/b55c3a70ce31104db7f5707fe1877cff to your computer and use it in GitHub Desktop.
Multi theme in jetpack compose
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// # 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)!! | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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