Reputation: 587
In a MAUI project I want to adopt a different colorAccent
value according to the theme of the application.
I tried to adopt this solution https://learn.microsoft.com/en-us/answers/questions/241870/how-to-customize-coloraccent-when-changing-the-the, from the Xamarin.Forms era, with a small modification of the code in the MainActivity.cs
:
public override void OnConfigurationChanged(Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
if (Microsoft.Maui.Controls.Application.Current.RequestedTheme == AppTheme.Dark)
{
this.SetTheme(Resource.Style.DarkTheme);
}
else
{
this.SetTheme(Resource.Style.MainTheme);
}
}
I also have set android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
property in the activity
tag of AndroidManfest.xml
, but the problem is that the execution of the code never enters the body of OnConfigurationChanged
.
Is there another approach that works for MAUI?
Upvotes: 0
Views: 209
Reputation: 14469
but the problem is that the execution of the code never enters the body of OnConfigurationChanged.
The OnConfigurationChanged
will be triggered when the system theme changed not the app's theme chanaged.
You can refer to the official document: User expectations of Runtime changes.
And if you want do something when change Application.Current.UserAppTheme
. You can use Application.Current.RequestedThemeChanged.
I used it in the MainActivity:
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
App.Current.RequestedThemeChanged += (s, e) =>
{
if (Microsoft.Maui.Controls.Application.Current.RequestedTheme == AppTheme.Dark)
{
this.SetTheme(Resource.Style.DarkTheme);
}
else
{
this.SetTheme(Resource.Style.MainTheme);
}
};
}
Edit:
You need to recreate the activity if you want to change its theme at runtime. And call the SetTheme()
in the Activity's OnCreate
method.
In the Platforms\Andorid\Resources\values\colors.xml:
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
<color name="colorAccentDark">#FF0000</color>
</resources>
In the Platforms\Andorid\Resources\values\styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DarkTheme" parent="Theme.MaterialComponents.DayNight">
<item name="colorPrimary">@color/colorAccentDark</item>
<item name="colorPrimaryDark">@color/colorAccentDark</item>
<item name="colorAccent">@color/colorAccentDark</item>
<item name="android:actionMenuTextColor">@color/colorActionMenuTextColor</item>
<item name="appBarLayoutStyle">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
<item name="bottomNavigationViewStyle">@style/Widget.Design.BottomNavigationView</item>
<item name="materialButtonStyle">@style/MauiMaterialButton</item>
<item name="checkboxStyle">@style/MauiCheckBox</item>
<item name="android:textAllCaps">false</item>
<item name="alertDialogTheme">@style/MauiAlertDialogTheme</item>
</style>
</resources>
In the MainActivity:
[Activity(Theme = "@style/Maui.MainTheme.NoActionBar", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
static bool IsDarkTheme = false;
protected override void OnCreate(Bundle? savedInstanceState)
{
App.Current.RequestedThemeChanged += (s, e) =>
{
if(Microsoft.Maui.Controls.Application.Current.UserAppTheme == AppTheme.Dark)
IsDarkTheme = true;
else
IsDarkTheme = false;
};
if (IsDarkTheme)
SetTheme(Resource.Style.DarkTheme);
else
SetTheme(Resource.Style.MainTheme);
base.OnCreate(savedInstanceState);
}
}
I used the static bool variable. You can use the preference to store the value instead.
Finally, recreate the activity when you change the theme:
Application.Current.UserAppTheme = AppTheme.Dark;
#if ANDROID
Platform.CurrentActivity.Recreate();
#endif
In my test, the default theme [Activity(Theme = "@style/Maui.SplashTheme"
will make the this.SetTheme(Resource.Style.DarkTheme);
not work. If you change the SplashTheme to other theme, such as MainTheme, Maui.MainTheme.NoActionBar and so on, the accent color will also change. But this will break the splash screen.
Upvotes: 1