Lily Monta
Lily Monta

Reputation: 15

How to Implement Real-Time Theme Switching in Android with Kotlin?

I'm working on an Android app in Kotlin and want to allow users to toggle between light and dark themes in real-time, without restarting the app. I've tried using the AppCompatDelegate.setDefaultNightMode() method, but the theme doesn't update immediately across all screens.

Here's what I've done so far:

  1. Added a Switch in the app's settings screen for toggling themes.
  2. Used AppCompatDelegate.setDefaultNightMode() to apply the theme based on the switch's state.

However, only the current screen refreshes, and navigating to other screens doesn't apply the theme immediately. Is there a way to implement real-time theme switching across the entire app without restarting it? Should I be using LiveData, ViewModel, or something else to observe theme changes globally?

I want the theme to apply immediately across the entire app after switching, without needing to restart or navigate back to the home screen.

Upvotes: 1

Views: 102

Answers (1)

Benjamin Lawson
Benjamin Lawson

Reputation: 21

This is the utility class that I used to change themes based on user choices.

object ThemeHelper {
    private const val TAG: String = "ThemeHelper"

    var currentTheme: String? = null

    fun applyTheme(activity: Activity?) {
        val sessionManager = SessionManager(activity)
        val theme: String = sessionManager.getStringValue(Const.THEME_KEY)
        Log.d(TAG, "applyTheme: theme = $theme")

        if (theme != currentTheme) {
            when (theme) {
                Const.THEME_LIGHT -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
                Const.THEME_DARK -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
                Const.THEME_SYSTEM -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
                else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
            }
            currentTheme = theme

            val delegate = AppCompatDelegate.create(activity!!, null)
            delegate.applyDayNight()
        }
    }
}

I hope it's helpful to you.

Upvotes: 0

Related Questions