6

I'm using Theme.Material.Components.DayNight theme to implement dark mode in my app. The problem is my dark mode will be purely compounded with dark components while my "light" mode will be coumpounded with mixed dark and light components. So i need to access somehow dark themed atrtributes when app default mode is set to Light. Could you help me to solve my problem?

I was thinking about setting custom theme "DarkThemeInLight" and assign it to views which should be dark but is it a good approach? If i set colors directly in that theme definition i will repeat almost half code from colors.xml(night).

Approach i was thinking about:

     <style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorSecondary">@color/colorSecondary</item>
        <item name="android:colorBackground">@color/colorBackground</item>
        <item name="colorSurface">@color/colorSurface</item>
        <item name="colorError">@color/colorOnError</item>
        <item name="colorOnPrimary">@color/colorOnPrimary</item>
        <item name="colorOnSecondary">@color/colorOnSecondary</item>
        <item name="colorOnBackground">@color/colorOnBackground</item>
        <item name="colorOnSurface">@color/colorOnSurface</item>
        <item name="colorOnError">@color/colorOnError</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="drawerArrowStyle">@style/DrawerIcon</item>
        <item name="textAppearanceSubtitle1">@style/TextAppearance.MyTheme.Subtitle1</item>
        <item name="textAppearanceSubtitle2">@style/TextAppearance.MyTheme.Subtitle2</item>
        <item name="textAppearanceCaption">@style/TextAppearance.MyTheme.Caption</item>
        <item name="android:colorControlActivated">@color/colorPrimary</item>
    </style>

    <style name="DarkThemeInLight" parent="AppTheme">
        <item name="android:colorBackground">@night/colorsBackground</item> (Can i call night folder somehow?)
        or
        <item name="android:colorBackground">#121212</item> (Value from night colors folder)
        ...
    </style>

Update 04.06.2020:

Ultimately, I was able to achieve the effect I mentioned. Thanks to the definition of two separate AppTheme and AppTheme.Dark styles, I am able to stylize some components as light and others as dark, but my solution excludes the possibility of switching between light and dark modes so my question is still open

    <style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorSecondary">@color/colorSecondary</item>
        <item name="android:colorBackground">@color/colorBackground</item>
        <item name="colorSurface">@color/colorSurface</item>
        <item name="colorError">@color/colorError</item>
        <item name="colorOnPrimary">@color/colorOnPrimary</item>
        <item name="colorOnSecondary">@color/colorOnSecondary</item>
        <item name="colorOnBackground">@color/colorOnBackground</item>
        <item name="colorOnSurface">@color/colorOnSurface</item>
        <item name="colorOnError">@color/colorOnError</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:statusBarColor">@color/colorSurfaceNight</item>
        <item name="android:navigationBarColor">@color/colorSurfaceNight</item>
        <item name="android:navigationBarDividerColor" tools:targetApi="o_mr1">
            @color/colorSurfaceNight
        </item>
        <item name="drawerArrowStyle">@style/DrawerIcon</item>
        <item name="textAppearanceSubtitle1">@style/TextAppearance.MyTheme.Subtitle1</item>
        <item name="textAppearanceSubtitle2">@style/TextAppearance.MyTheme.Subtitle2</item>
        <item name="textAppearanceCaption">@style/TextAppearance.MyTheme.Caption</item>
        <item name="android:colorControlActivated">@color/colorPrimary</item>
    </style>

    <style name="AppTheme.Dark" parent="Theme.MaterialComponents">
        <item name="colorPrimary">@color/colorPrimaryNight</item>
        <item name="android:colorBackground">@color/colorBackgroundNight</item>"
        <item name="colorSecondary">@color/colorSecondaryNight</item>
        <item name="colorSurface">@color/colorSurfaceNight</item>
        <item name="colorError">@color/colorErrorNight</item>
        <item name="colorOnPrimary">@color/colorOnPrimaryNight</item>
        <item name="colorOnSecondary">@color/colorOnSecondaryNight</item>
        <item name="colorOnBackground">@color/colorOnBackgroundNight</item>
        <item name="colorOnSurface">@color/colorOnSurfaceNight</item>
        <item name="colorOnError">@color/colorOnErrorNight</item>
    </style>
    ```
Swierszczu
  • 159
  • 2
  • 9
  • In any case `@night/colorsBackground` is **not** possible. – Gabriele Mariotti Nov 19 '19 at 07:35
  • In my experience the best way is to define a single theme with `Theme.MaterialComponents.DayNight` and then use the **`-night` qualifier** on your resource folders as `drawable-night` and `values-night` to define values for the dark theme. – Gabriele Mariotti Nov 19 '19 at 07:39
  • @GabrieleMariotti yeah, i am using it.But values from colors-night folder only affect my layout when using dark mode and I need to use them on some views also when i'm in light mode. – Swierszczu Nov 19 '19 at 07:44
  • I've just check my approach and it doesn't even work when i assign colors directly and set theme to view. `#121212` – Swierszczu Nov 19 '19 at 07:46

1 Answers1

7

i think for solve this problem you need do this steps:

  1. create values-night directory in main/res/.
  2. copy colors.xml file from main/res/values/ and paste Inside values-night.
  3. change color value in main/res/values-night/colors.xml to dark.(don't change name , just change value)
  4. use color from your app style.
  5. go to onCreate method in mainActivity and use this code for change theme:

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);

AppCompatDelegate.MODE_NIGHT_YES use for dark mode and AppCompatDelegate.MODE_NIGHT_NO for day mode.

Milad Targholi
  • 102
  • 1
  • 8
  • 3
    You are right, but despite the fact that the phone has a light mode option set, some components need to be styled as dark. However, all components within a dark style should be stylized as dark. – Swierszczu Jun 04 '20 at 20:15
  • 1
    @Swierszczu did you use theme overlays for setting the dark themed surfaces above light theme and viceversa? – Marlon López Aug 14 '21 at 01:42