Home > database >  Xamarin Forms - Tell Android to switch style theme at runtime
Xamarin Forms - Tell Android to switch style theme at runtime

Time:11-22

In Xamarin Forms, in my settings page, I have a switch to toogle between Light and Dark theme.

And whenever I switch theme then I use MessagingCenter to tell all listeners that the theme has changed.

In my CustomPickerRenderer for iOS I have this code to tell the Picker to switch themes.

[assembly: ExportRenderer(typeof(Picker), typeof(CustomPickerRenderer))]
namespace CykelStaden.iOS.Renderers
{
    public class CustomPickerRenderer : PickerRenderer
    {   
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);

            MessagingCenter.Subscribe<object, string>(this, "ThemeIsDark", (sender, arg) =>
            {
                this.OverrideUserInterfaceStyle = UIUserInterfaceStyle.Dark;
            });

            MessagingCenter.Subscribe<object, string>(this, "ThemeIsLight", (sender, arg) =>
            {
                this.OverrideUserInterfaceStyle = UIUserInterfaceStyle.Light;
            });
        }
    }
}

Now the above code for iOS is working great, but how can I write the same code for CustomPickerRenderer for Android

I have been searching for 2 days now and I cannot figure out how to do it.

Please help me out.

CodePudding user response:

I think you are looking for something like this

Application.Current.RequestedThemeChanged  = (s, a) =>
{
   Config.LoadTheme();
};

This repository contains sample app which change theme at runtime on Android and Windows so you can try.

CodePudding user response:

You could refer to the code below:

I set the style in the App.xaml. You could add the theme from the file as well.

 <Application.Resources>
    <ResourceDictionary>
        <Style TargetType="Picker" x:Key="DarkTheme">
            <Setter Property="BackgroundColor" Value="Black"></Setter>
            <Setter Property="TextColor" Value="White"></Setter>
        </Style>
        <Style TargetType="Picker" x:Key="LightTheme">
            <Setter Property="BackgroundColor" Value="White"></Setter>
            <Setter Property="TextColor" Value="Black"></Setter>
        </Style>
    </ResourceDictionary>
</Application.Resources>

Xaml:

  <Picker x:Name="picker" Title="Select a Theme" TitleColor="Green" SelectedIndexChanged="picker_SelectedIndexChanged">
            <Picker.ItemsSource>
                <x:Array Type="{x:Type x:String}">
                    <x:String>Dark</x:String>
                    <x:String>Light</x:String>
                </x:Array>
            </Picker.ItemsSource>
        </Picker>

Code behind:

 public Page10()
    {
        InitializeComponent();
        picker.Style = (Style)App.Current.Resources["DarkTheme"];
    }

    private void picker_SelectedIndexChanged(object sender, EventArgs e)
    {

        switch (picker.SelectedItem.ToString())
        {
            case "Dark":
                MessagingCenter.Send<Page10>(this, "Dark");
                break;

            case "Light":
                MessagingCenter.Send<Page10>(this, "Light");
                break;
        }
    }
    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        MessagingCenter.Unsubscribe<Page10>(this, "Dark");
        MessagingCenter.Unsubscribe<Page10>(this, "Light");
    }

Custom renderer:

[assembly: ExportRenderer(typeof(Picker), typeof(CustomPickerRenderer))]
namespace App15.Droid
{
class CustomPickerRenderer : PickerRenderer
{
    public CustomPickerRenderer(Context context) : base(context)
    {

    }
    protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
    {
        base.OnElementChanged(e);
        var picker = e.NewElement as Picker;
        MessagingCenter.Subscribe<Page10>(this, "Dark", (sender) =>
        {
            picker.Style = (Style)App.Current.Resources["DarkTheme"];
        });
        MessagingCenter.Subscribe<Page10>(this, "Light", (sender) =>
        {
            picker.Style = (Style)App.Current.Resources["LightTheme"];
        });
    }
}
}
  • Related