diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue13356.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue13356.cs new file mode 100644 index 000000000000..6fb670eb5ec1 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue13356.cs @@ -0,0 +1,85 @@ +#if ANDROID +using Android.Content; +using Android.OS; +using View = Android.Views.View; +using Google.Android.Material.BottomSheet; +#endif +using Microsoft.Maui.Platform; +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 13356, "Java.Lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponent.", PlatformAffected.Android)] +public class Issue13356 : TestContentPage +{ + protected override void Init() + { + var stack = new VerticalStackLayout + { + Spacing = 25, + Padding = new Thickness(30, 0), + VerticalOptions = LayoutOptions.Center, + Children = + { + CreateButton("Show Button Dialog", "showButtonDialogButton", Button_Dialog_clicked), + CreateButton("Show CheckBox Dialog", "showCheckBoxDialogButton", CheckBox_Dialog_clicked), + } + }; + + Content = new ScrollView { Content = stack }; + } + + Button CreateButton(string text, string automationId, EventHandler eventHandler) => + new() + { + Text = text, + AutomationId = automationId, + HorizontalOptions = LayoutOptions.Center, + Command = new Command(() => eventHandler?.Invoke(this, EventArgs.Empty)) + }; + + void Button_Dialog_clicked(object sender, EventArgs e) + { +#if ANDROID + var droidContext = Handler.MauiContext.Context; + using var myDialog = new Issue13356Dialog(droidContext) + { + Content = new Button { Text = "Dialog Button", Padding = new Thickness(30) } + .ToPlatform(Application.Current.Handler.MauiContext) + }; + myDialog.ShowDialog(); +#endif + } + + void CheckBox_Dialog_clicked(object sender, EventArgs e) + { +#if ANDROID + var droidContext = Handler.MauiContext.Context; + using var myDialog = new Issue13356Dialog(droidContext) + { + Content = new CheckBox(){AutomationId = "DialogCheckBox" } + .ToPlatform(Application.Current.Handler.MauiContext) + }; + myDialog.ShowDialog(); +#endif + } + +#if ANDROID + public class Issue13356Dialog : BottomSheetDialog + { + public View Content { get; set; } + + public Issue13356Dialog(Context context) : base(context) { } + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + SetContentView(Content); + } + + public void ShowDialog() + { + if (!IsShowing) + Show(); + } + } +#endif +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue13356.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue13356.cs new file mode 100644 index 000000000000..36a3a68981c8 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue13356.cs @@ -0,0 +1,35 @@ +#if ANDROID // This Issue is only reproduced in Android platform +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue13356 : _IssuesUITest +{ + public Issue13356(TestDevice testDevice) : base(testDevice) + { + } + + protected override bool ResetAfterEachTest => true; + public override string Issue => "Java.Lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponent."; + + [Test] + [Category(UITestCategories.Button)] + public void DialogButtonAppearsWhenMaterialButtonIsTapped() + { + App.WaitForElement("showButtonDialogButton"); + App.Tap("showButtonDialogButton"); + App.WaitForElement("Dialog Button"); + } + + [Test] + [Category(UITestCategories.CheckBox)] + public void DialogButtonAppearsWhenMaterialCheckBoxIsTapped() + { + App.WaitForElement("showCheckBoxDialogButton"); + App.Tap("showCheckBoxDialogButton"); + App.WaitForElement("DialogCheckBox"); + } +} +#endif \ No newline at end of file diff --git a/src/Core/src/Handlers/CheckBox/CheckBoxHandler.Android.cs b/src/Core/src/Handlers/CheckBox/CheckBoxHandler.Android.cs index 91dd6009921a..c56c858e0933 100644 --- a/src/Core/src/Handlers/CheckBox/CheckBoxHandler.Android.cs +++ b/src/Core/src/Handlers/CheckBox/CheckBoxHandler.Android.cs @@ -9,7 +9,7 @@ public partial class CheckBoxHandler : ViewHandler { protected override AppCompatCheckBox CreatePlatformView() { - var platformCheckBox = new MaterialCheckBox(Context) + var platformCheckBox = new MaterialCheckBox(MauiMaterialContextThemeWrapper.Create(Context)) { SoundEffectsEnabled = false }; diff --git a/src/Core/src/Platform/Android/MauiMaterialButton.cs b/src/Core/src/Platform/Android/MauiMaterialButton.cs index 2a1144a702ee..6b077f79333f 100644 --- a/src/Core/src/Platform/Android/MauiMaterialButton.cs +++ b/src/Core/src/Platform/Android/MauiMaterialButton.cs @@ -23,7 +23,7 @@ public class MauiMaterialButton : MaterialButton internal const int IconGravityBottom = 0x1000; public MauiMaterialButton(Context context) - : base(context) + : base(MauiMaterialContextThemeWrapper.Create(context)) { } @@ -31,11 +31,11 @@ protected MauiMaterialButton(nint javaReference, JniHandleOwnership transfer) : { } - public MauiMaterialButton(Context context, IAttributeSet? attrs) : base(context, attrs) + public MauiMaterialButton(Context context, IAttributeSet? attrs) : base(MauiMaterialContextThemeWrapper.Create(context), attrs) { } - public MauiMaterialButton(Context context, IAttributeSet? attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) + public MauiMaterialButton(Context context, IAttributeSet? attrs, int defStyleAttr) : base(MauiMaterialContextThemeWrapper.Create(context), attrs, defStyleAttr) { } diff --git a/src/Core/src/Platform/Android/MauiMaterialContextThemeWrapper.cs b/src/Core/src/Platform/Android/MauiMaterialContextThemeWrapper.cs new file mode 100644 index 000000000000..f2ddde546370 --- /dev/null +++ b/src/Core/src/Platform/Android/MauiMaterialContextThemeWrapper.cs @@ -0,0 +1,26 @@ +using Android.Content; +using Android.Views; + +namespace Microsoft.Maui.Platform; + +internal class MauiMaterialContextThemeWrapper : ContextThemeWrapper +{ + public MauiMaterialContextThemeWrapper(Context context) : this(context, Resource.Style.Maui_MainTheme_Base) + { + } + + MauiMaterialContextThemeWrapper(Context context, int themeResId) : base(context, themeResId) + { + + } + + public static MauiMaterialContextThemeWrapper Create(Context context) + { + if (context is MauiMaterialContextThemeWrapper materialContext) + { + return materialContext; + } + + return new MauiMaterialContextThemeWrapper(context); + } +}