Skip to content

Commit cda3eb3

Browse files
Android: fix dialog button colors in dark mode (#15091)
* Core(Android): fix dialog button colors in dark mode Fix alert dialog button colors in dark mode. Use ?attr/colorOnSurface for text color in dialogs. This ensures contrasting color for both dark and light modes. * Core(Android): use AppCompat alert dialog in picker Use AppCompat version of AlertDialog in picker. This ensures consistent styling between picker dialog and alert dialog. * Controls.DeviceTests: add AlertDialogTests Add tests for checking brightness of AlertDialog button text. Co-authored-by: webwarrior <[email protected]> --------- Co-authored-by: Parham Saremi <[email protected]>
1 parent 2ac61e5 commit cda3eb3

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Microsoft.Maui.DeviceTests.Stubs;
7+
using Microsoft.Maui.Platform;
8+
using Xunit;
9+
using AndroidX.AppCompat.App;
10+
using Android.Graphics;
11+
12+
namespace Microsoft.Maui.DeviceTests
13+
{
14+
public partial class AlertDialogTests: ControlsHandlerTestBase
15+
{
16+
17+
async Task<Color> GetDialogButtonTextColor(int nightMode)
18+
{
19+
var mauiContextStub1 = new ContextStub(ApplicationServices);
20+
var activity = mauiContextStub1.GetActivity();
21+
mauiContextStub1.Context = new Android.Views.ContextThemeWrapper(activity, Resource.Style.Maui_MainTheme_NoActionBar);
22+
Color color = Color.Transparent;
23+
await InvokeOnMainThreadAsync(() =>
24+
{
25+
var initialNightMode = activity.Delegate.LocalNightMode;
26+
activity.Delegate.SetLocalNightMode(nightMode);
27+
var builder = new AlertDialog.Builder(activity);
28+
var alertDialog = builder.Create();
29+
alertDialog.Show();
30+
var button = alertDialog.GetButton((int)Android.Content.DialogButtonType.Negative);
31+
var textColor = button.CurrentTextColor;
32+
color = new Color(textColor);
33+
activity.Delegate.SetLocalNightMode(initialNightMode);
34+
alertDialog.Hide();
35+
});
36+
37+
return color;
38+
}
39+
40+
[Fact]
41+
public void AlertDialogButtonColorLightTheme()
42+
{
43+
var textColor = GetDialogButtonTextColor(AppCompatDelegate.ModeNightNo).Result;
44+
Assert.True(textColor.GetBrightness() < 0.5);
45+
}
46+
47+
[Fact]
48+
public void AlertDialogButtonColorDarkTheme()
49+
{
50+
var textColor = GetDialogButtonTextColor(AppCompatDelegate.ModeNightYes).Result;
51+
Assert.True(textColor.GetBrightness() > 0.5);
52+
}
53+
}
54+
}

src/Core/src/Handlers/Picker/PickerHandler.Android.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
using Android.Text;
77
using Android.Text.Style;
88
using AResource = Android.Resource;
9+
using AppCompatAlertDialog = AndroidX.AppCompat.App.AlertDialog;
910

1011
namespace Microsoft.Maui.Handlers
1112
{
1213
public partial class PickerHandler : ViewHandler<IPicker, MauiPicker>
1314
{
14-
AlertDialog? _dialog;
15+
AppCompatAlertDialog? _dialog;
1516

1617
protected override MauiPicker CreatePlatformView() =>
1718
new MauiPicker(Context);
@@ -108,7 +109,7 @@ void OnClick(object? sender, EventArgs e)
108109
{
109110
if (_dialog == null && VirtualView != null)
110111
{
111-
using (var builder = new AlertDialog.Builder(Context))
112+
using (var builder = new AppCompatAlertDialog.Builder(Context))
112113
{
113114
if (VirtualView.TitleColor == null)
114115
{

src/Core/src/Platform/Android/PickerExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ internal static void UpdatePicker(this MauiPicker platformPicker, IPicker picker
4747
platformPicker.Text = picker.GetItem(picker.SelectedIndex);
4848
}
4949

50-
internal static void UpdateFlowDirection(this AlertDialog alertDialog, MauiPicker platformPicker)
50+
internal static void UpdateFlowDirection(this AndroidX.AppCompat.App.AlertDialog alertDialog, MauiPicker platformPicker)
5151
{
5252
var platformLayoutDirection = platformPicker.LayoutDirection;
5353

src/Core/src/Platform/Android/Resources/values/styles.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<item name="materialButtonStyle">@style/MauiMaterialButton</item>
1212
<item name="checkboxStyle">@style/MauiCheckBox</item>
1313
<item name="android:textAllCaps">false</item>
14+
<item name="alertDialogTheme">@style/MauiAlertDialogTheme</item>
1415
</style>
1516
<style name="Maui.MainTheme.NoActionBar" parent="Maui.MainTheme">
1617
<item name="windowActionBar">false</item>
@@ -66,6 +67,10 @@
6667
<item name="android:minHeight">0dp</item>
6768
</style>
6869

70+
<style name="MauiAlertDialogTheme" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
71+
<item name="colorPrimary">?attr/colorOnSurface</item>
72+
</style>
73+
6974
<!--
7075
The collectionViewScrollBars style will be used as the default style for ItemsViewRenderer (the base renderer
7176
for CollectionView and CarouselView. We have to use a style to set up the scrollbars because there is currently

0 commit comments

Comments
 (0)