4
votes

in my application I want to implement multiple themes (Light and Dark), this, I created 2 ResourceDictionary XAML files with the exact same key names and I merge them to App.xaml depending on the on going required theme.

The problem comes with Android/IOS specific properties existsing in XML (in Android for example) where they don't obey the App.xaml file. So I end up with my application in dark theme for example with <TimePicker/> element for example with colors of the default light theme.

So I would like to be able to change Android XML colors file colors.xml and styles.xml parameters an its equivalent in IOS depending on my needs, changing the color accent for example and so on.

Thanks in advance ^^.

=============== Update 1 ===============

Maybe if I can make the XML file get its value from a dynamic resource, app property or a code ? I can make the change theme event set the resource or the app property or even make a code that dynamically decides which values to be put.

Any help ?

=============== Update 2 ===============

Maybe we can just override the colors.xml and styles.xml files with another way? Or maybe create 2 color.xml and styles.xml files and load them according to a code ?!

1
I think you are in the correct track. just switch xml file dynamically in code level. add some code you have done until this point. then we can help you. - Supun Liyanaarachchi
Well, can you help me out with that ? How to switch xml files dynamically ? - Mohamed Ashraf
You could refer to the link below: stackoverflow.com/questions/48465053/… - Wendy Zang - MSFT
It doesn't tell me how to do it, instead, they are talking about XAML not XML, there is a comment talking about XML but doesn't tell me how to switch XML styles... - Mohamed Ashraf
The link suggest to set the style in style.xml. And you could try to reset the style at runtime. - Wendy Zang - MSFT

1 Answers

1
votes

When a theme is selected at runtime, the application should:

  1. Remove the current theme from the application. This is achieved by clearing the MergedDictionaries property of the application-level ResourceDictionary.

  2. Load the selected theme. This is achieved by adding an instance of the selected theme to the MergedDictionaries property of the application-level ResourceDictionary.

Any VisualElement objects that set properties with the DynamicResource markup extension will then apply the new theme values. This occurs because the DynamicResource markup extension maintains a link to dictionary keys. Therefore, when the values associated with keys are replaced, the changes are applied to the VisualElement objects.

In the sample application, a theme is selected via a modal page that contains a Picker. The following code shows the OnPickerSelectionChanged method, which is executed when the selected theme changes:

void OnPickerSelectionChanged(object sender, EventArgs e)
{
    Picker picker = sender as Picker;
    Theme theme = (Theme)picker.SelectedItem;

ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
    mergedDictionaries.Clear();

    switch (theme)
    {
        case Theme.Dark:
            mergedDictionaries.Add(new DarkTheme());
            break;
        case Theme.Light:
        default:
            mergedDictionaries.Add(new LightTheme());
            break;
    }
}
}

source -https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/theming/theming#load-a-theme-at-runtime

and this post will help you https://www.sharpnado.com/dark-light-mode/

for more -https://docs.microsoft.com/en-us/xamarin/android/user-interface/material-theme