I have a Compose-only application that gives users three options of theming:
- System
- Light
- Dark
The theme is changed in Activity's onCreate() method by passing darkTheme argument to my app's theme Composable function.
If System is selected and Android system supports Dark mode (Android 10+), everything works fine.
But if Dark is selected, the dark theme defined in Compose is applied, however the system navigation bar at the bottom stays white.
Then I went to the res/values/themes.xml file and it looked like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.ExampleApp" parent="android:Theme.Material.Light.NoActionBar" />
</resources>
So, I assume that the system navigation bar stays white, because in Compose the default theme is android:Theme.Material.Light.NoActionBar and we can't control its color from Compose code.
This is not a big problem for Android 10+ devices, because they can simply select System option, and then manually turn on/off the system Dark mode from within the Android.
But for the devices that don't support the system Dark mode, they navigation bar stays white, which looks terrible.
So, I did some searching and found a way to "fix" this (mainly from this article).
- First, I changed the parent theme in
styles.xmlfile to the following:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.ExampleApp" parent="Theme.AppCompat.DayNight" />
</resources>
- This doesn't work unless your activity extends
AppCompatActivity. Default Compose-only applications have their activity extendComponentActivity. So:
class MainActivity : AppCompatActivity()
- Then I switch to so-called "Night mode" using the following functions:
// For SDK <= 30
AppCompatDelegate.setDefaultNightMode()
// For SDK >= 31
uiManager.setApplicationNightMode()
And it works!
However, I have some concerns and questions regarding this method.
Is it OK to use the
Theme.AppCompat.DayNightstyle for Compose-only application? It seems really old and I wonder if it breaks something in Compose.What are the drawbacks of using
AppCompatActivityinstead ofComponentActivityin Compose-only applications? I don't useFragments, so I don't really need it, but maybe again, it breaks something in Compose? Does it increase .apk size?I don't know which parameters to call the functions
setDefaultNightMode()andsetApplicationNightMode()with for "Follow the system theme" mode. For the first one there isMODE_NIGHT_FOLLOW_SYSTEM, but the second function doesn't have it, and only hasMODE_NIGHT_AUTOandMODE_NIGHT_CUSTOM. They both say that they switch to "Night mode" based on the current time, which I don't really want. For Android 10+ I don't want them to break their nativeDark modefunctionality.
If system status or navigation bars are not changing with in-app set theme, make sure to:
android:windowLightStatusBarandandroid:windowLightNavigationBarfromthemes.xml.isAppearanceLightStatusBarsandisAppearanceLightNavigationBarsonWindowInsetsControllerCompatin your Compose theme.