material-components / material-components-android

Modular and customizable Material Design UI components for Android
Apache License 2.0
16.08k stars 3.04k forks source link

[MaterialAlertDialogBuilder] Unable to configure dialog background color #3482

Closed seadowg closed 11 months ago

seadowg commented 11 months ago

Description: I'm unable to change the background color of dialogs created using MaterialAlertDialogBuilder using the approach documented at https://github.com/material-components/material-components-android/blob/master/docs/components/Dialog.md. Changing the backgroundTint attribute (as shown in the example below) does not change the color of the background.

As a side note, the docs state that the default background color should be ?attr/colorSurface, whereas it appears to actually be a low opacity version of ?attr/colorPrimary. Are the docs incorrect here or am I misunderstanding something?

Expected behavior: The background color should change based on the backgroundTint attribute in a custom materialAlertDialogTheme overlay.

Source code:

In the theme:

<item name="materialAlertDialogTheme">@style/ThemeOverlay.App.MaterialAlertDialog</item>

The overlay:

<style name="ThemeOverlay.App.MaterialAlertDialog" parent="ThemeOverlay.Material3.MaterialAlertDialog">
        <item name="backgroundTint">#fafcff</item>
</style>

Material Library version: 1.10.0-alpha05

pekingme commented 11 months ago

Thanks for reaching out. I think you need one more layer. You should define/override theme (not style) attributes in a theme overlay. Define a dialog style overriding the backgroundTint and assign it like https://github.com/material-components/material-components-android/blob/0a6a8a971dbeffa47359fa83bf8719ccaa6a21e7/lib/java/com/google/android/material/dialog/res/values/themes_overlay.xml#L95 in the theme overlay. Let me know if it's not working.

pekingme commented 11 months ago

As a side note, the docs state that the default background color should be ?attr/colorSurface, whereas it appears to actually be a low opacity version of ?attr/colorPrimary. Are the docs incorrect here or am I misunderstanding something?

The container color is surface color + elevation overlay (colorPrimary with opacity based on elevation).

https://github.com/material-components/material-components-android/blob/0a6a8a971dbeffa47359fa83bf8719ccaa6a21e7/lib/java/com/google/android/material/dialog/MaterialAlertDialogBuilder.java#L136

https://github.com/material-components/material-components-android/blob/0a6a8a971dbeffa47359fa83bf8719ccaa6a21e7/lib/java/com/google/android/material/dialog/MaterialAlertDialogBuilder.java#L161

seadowg commented 11 months ago

Thanks for reaching out. I think you need one more layer. You should define/override theme (not style) attributes in a theme overlay.

Ah right! So to change the background color you need to set a custom materialAlertDialogTheme that's an overlay that in turn overrides alertDialogStyle with a style that sets backgroundTint. That appears to work!

Unfortunately, I was looking to change the color so that it's colorSurface as we've found that some our dialog designs do not work with the new elevation system in Material 3 (where we end up with what looks like a low emphasis/opacity version of colorPrimary). Are we able to customise the colors used at each elevation?

seadowg commented 11 months ago

To answer my own question, yes there is! From "Using Surface Colors":

Material 3 uses primary colored elevation overlays to present a visual hierarchy with different elevations in both light and dark themes. Material 3 themes enable this by default with setting ?attr/elevationOverlayColor to ?attr/colorPrimary.

So, you can override elevationOverlayColor to customise the color applied at higher elevations.

bubbleguuum commented 11 months ago

You can also disable the elevation overlay with something like this which I believe will result in the background of the dialog to be colorSurface.

  <style name="ThemeOverlay.Util.DisableElevationOverlay" parent="">
        <item name="elevationOverlayEnabled">false</item>
    </style>
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(
    new ContextThemeWrapper(context, R.style.ThemeOverlay_Util_EnableElevationOverlay));