Search code examples
xamarinxamarin.formsxamarin.androiddarkmodeandroid-dark-theme

Getting system theme setting of Android in Xamarin.Forms


I have three radio buttons for selecting my app's theme: Default, which should apply whichever theme is selected in Android's system settings, Light and Dark.

The problem is that whenever I select the Default radio button it doesn't return a standard value as I am expecting, but either OSAppTheme.Light or OSAppTheme.Dark, whichever the previous setting was. In other words it reapplies the previous setting.

Here is my code:

    private void DarkMode(object sender, CheckedChangedEventArgs e)
    {
        if (defaultRadioButton.IsChecked == true)
        {
            if (Application.Current.RequestedTheme != OSAppTheme.Unspecified)
            {
                Application.Current.UserAppTheme = Application.Current.RequestedTheme;
            }
            else
            {
                Application.Current.UserAppTheme = OSAppTheme.Light;
            }
        }
        else if (lightRadioButton.IsChecked == true)
        {
            Application.Current.UserAppTheme = OSAppTheme.Light;
        }
        else if (darkRadioButton.IsChecked == true)
        {
            Application.Current.UserAppTheme = OSAppTheme.Dark;
        }
     }

I had the impression that Application.Current.RequestedTheme always carried the system's setting, which I guess from the behavior I'm encountering isn't true.

If Application.Current.RequestedTheme doesn't get the system's theme setting, then which is the correct way to detect if a user has enabled Dark Mode at the OS level?


Solution

  • According to this case about Manually apply dark theme in Xamarin.Forms, the Application.Current.UserAppTheme only applys for the theme defined with AppThemeBinding.

    So if you want to change the UI's theme with this property, you need to use the AppThemeBinding in your control such as the example code in the official document.

    In addition, the Application.Current.RequestedTheme can really get the device's system's current theme. But you can also try to get the android device's current theme with the following code in the MainActivity:

    var theme = this.Resources.Configuration.UiMode & Android.Content.Res.UiMode.NightMask;
    //if the value is Android.Content.Res.UiMode.NightNo means the device is using light mode
    //if the value is Android.Content.Res.UiMode.NightYes means the device is using dark mode
    

    And then you can declare a dark theme in the Project.Droid/Resource/values/style.xml and use it or just use the AppThemeBinding as the official document does to apply the dark theme in your application.

    Update

    1. Set the device's theme as dark
    2. Call the code above:
    Application.Current.UserAppTheme = OSAppTheme.Light;
    var theme = Application.Current.RequestedTheme;
    

    The value will be dark. It should be a bug, you can report it on the github.