how to customize colorAccent when changing the theme

delaio 306 Reputation points
2021-01-22T16:58:28.083+00:00

Hello,

I am developing an application under xamarin.forms

I am using AppThemeBinding to apply colors suitable for light or dark theme:

App.xaml

            <Style TargetType="NavigationPage">  
                    <Setter Property="BarBackgroundColor"  
                        Value="{AppThemeBinding Light={StaticResource CColorBackNavigation},Dark={StaticResource SColorBackNavigation},Default={StaticResource CColorBackNavigation}}" />  
                    <Setter Property="BarTextColor"  
                        Value="{AppThemeBinding Light={StaticResource CColorTextNavigation},Dark={StaticResource SColorTextNavigation},Default={StaticResource CColorTextNavigation}}" />  
                </Style>  

how to dynamically activate the change of android theme?

resources>values>styles.xml

       <style name = "MainTheme" parent = "MainTheme.Base">  
         <item name = "colorAccent"> @ android: color / black </item>  
       </style>  
       <style name = "ThemeDark" parent = "Theme.AppCompat.DayNight">  
         <item name = "colorAccent"> @ android: color / white </item>  
       </style>  

I guess it's in MainActivity.cs but despite reading the learn.microsoft.com and developer.android.com docs, I haven't figured out how. I am also not sure that the parents of the themes are correct ("MainTheme.Base" and "Theme.AppCompat.DayNight")

Thanks for your help.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,294 questions
0 comments No comments
{count} votes

Accepted answer
  1. delaio 306 Reputation points
    2021-02-09T18:21:03.003+00:00

    Hello,

    Working on a new project with an incompatible colorAccent on the dark theme, I had to research how to dynamically change the color of colorAccent (Android) and I found the solution. If you see any error in this code that seems to be working fine, please let me know.

    Best regards,

    delaio.

    MyApply.Android > Resources > values > colors.xml

    <resources>  
      <color name="colorAccent">#000000</color>  
      <color name="colorAccentDark">#FFFFFF</color>  
    </resources>  
    

    MyApply.Android > Resources > values > styles.xml

    <resources>  
      <style name="MainTheme" parent="MainTheme.Base">  
        <item name="colorAccent">@color/colorAccent</item>  
      </style>  
      <style name="NightTheme" parent="MainTheme.Base">  
        <item name="colorAccent">@color/colorAccentDark</item>  
      </style>  
    </resources>  
    

    MyApply.Android > MainActivity.cs

            public override void OnConfigurationChanged(Configuration newConfig)  
            {  
                base.OnConfigurationChanged(newConfig);  
      
                if (Xamarin.Forms.Application.Current.RequestedTheme == OSAppTheme.Dark)  
                {  
                    this.SetTheme(Resource.Style.NightTheme);  
                }  
                else  
                {  
                    this.SetTheme(Resource.Style.MainTheme);  
                }  
            }  
    

    https://stackoverflow.com/questions/64256678/dynamically-change-androids-accent-color

    https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#config-changes

    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 68,571 Reputation points Microsoft Vendor
    2021-01-25T02:35:55.433+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    First of all, please clear following two styles.

    resources>values>styles.xml is related to the native android style.

    using AppThemeBinding to apply colors suitable for light or dark theme: use AppThemeBinding is xamarin forms style.

    how to dynamically activate the change of android theme?

    Blew styles, there two different styles, Android does not magically append ThemeDark or parent = "Theme.AppCompat.DayNight" to your theme at any point, regardless of whether or not the user enabled dark mode. You have android:theme="@STYLE /ThemeDark". So, Android will use ThemeDark all the time, and your MainTheme will not be used. If you want to exchange styles in native android, you should restart your application, apply the other styles with this.SetTheme(id); in onCreate() method of MainActivity.cs. Obviously, use native android change the theme is not elegant in Xamarin.Forms

       <style name = "MainTheme" parent = "MainTheme.Base">  
                 <item name = "colorAccent"> @ android: color / black </item>  
               </style>  
               <style name = "ThemeDark" parent = "Theme.AppCompat.DayNight">  
                 <item name = "colorAccent"> @ android: color / white </item>  
               </style>  
    

    If you want to use xamarin.forms to achieve switching the dark mode or light mode, please do not change the styles in resources>values>styles.xml, All the styles should be setted in the xamarin forms ResourceDictionary, you should reter to the following thread step by step to achieve basic switch dark/light theme.

    https://stackoverflow.com/a/61158088/10627299

    And I notice you have defined BarTextColor for navigation bar text color in styles, If you want to change the other controls text color, you need to define other styles like NavigationPage style in ContentPage.Resources.

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. delaio 306 Reputation points
    2021-01-25T14:17:15.34+00:00

    Hello LeonLu,

    Thanks for taking time to respond to me.

    Maybe my question was not clear: I want to use xamarin.forms to dynamically change dark mode or light mode depending on the system setting of the theme. Using AppThemeBinding seems to me to be very efficient and operational.

    I only have a problem with customizing the color of the radiobutton, the checkbox and the entry selection on android. The only solution I found currently is to change the color of "colorAccent" in the styles.xml file.

    Obviously, use native android change the theme is not elegant in Xamarin.Forms

    I totally agree but how do I customize the color of the radiobutton, checkbox and entry selection dynamically when the theme system settings change?

    The solution offered via MainActivity.cs is not dynamic: when the system theme changes, the application changes dynamically with AppThemeBinding but not the checkbox and entry selection radiobuttons: you have to restart the application, it's ugly.

    Is this possible with ResourceDictionary forms? I tried without success.


  3. delaio 306 Reputation points
    2021-01-29T18:50:37.68+00:00

    thank you very much LeonLu for the suggested alternative. it's a shame to have to redraw a radio button for a missing color property.

    I solved my problem by choosing a compatible color on the 2 dark and light themes.

    for those who would not have this possibility, I propose two other tracks that I found:

    MainPage.xaml

    <?xml version="1.0" encoding="utf-8" ?>  
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
                 xmlns:local="clr-namespace:test_custom_radiobutton_color"  
                 x:Class="test_custom_radiobutton_color.MainPage">  
      
        <StackLayout>  
            <RadioButton Content="classic radio button (color managed via .Android> Resources> values> colors.xml or styles.xml> colorAccent by default)" />  
            <local:MyRadioButton Content="radio button customized with green color (light theme) and blue color (dark theme)" />  
        </StackLayout>  
      
    </ContentPage>  
    

    test_custom_radiobutton_color > MyRadioButton.cs

    using Xamarin.Forms;  
      
    namespace test_custom_radiobutton_color  
    {  
        public class MyRadioButton: RadioButton  
        {  
        }  
    }  
    

    test_custom_radiobutton_color.Android > MyRadioButtonRenderer.cs

    using Android.Content;  
    using Android.Content.Res;  
    using test_custom_radiobutton_color;  
    using test_custom_radiobutton_color.Droid;  
    using Xamarin.Forms;  
    using Xamarin.Forms.Platform.Android;  
      
    [assembly: ExportRenderer(typeof(MyRadioButton), typeof(MyRadioButtonRenderer))]  
    namespace test_custom_radiobutton_color.Droid  
    {  
        public class MyRadioButtonRenderer : RadioButtonRenderer  
        {  
      
            public MyRadioButtonRenderer(Context context) : base(context)  
            {  
      
            }  
      
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.RadioButton> e)  
            {  
                base.OnElementChanged(e);  
      
                if (Control != null)  
                {  
                    if (Application.Current.RequestedTheme == OSAppTheme.Dark)  
                        // blue color  
                        Control.ButtonTintList = ColorStateList.ValueOf(global::Android.Graphics.Color.Rgb(122, 177, 230));  
                    else  
                        // green color  
                        Control.ButtonTintList = ColorStateList.ValueOf(global::Android.Graphics.Color.Rgb(79, 183, 67));  
                }  
            }  
        }  
    }