Reputation: 24572
I want to allow my user to select the AppTheme as he wants. Following are the options I want to give :-
I found a solution to use the below code:-
if(theme == App.Theme.Light)
{
Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightNo);
} else
{
Delegate.SetLocalNightMode(AppCompatDelegate.ModeNightYes);
}
But this code recreates the entire activity and on the click on the button, I am again taken to the LoginPage of my App.
Can anyone suggest me a way to programmatically change from Light Mode to Dark Mode in Xamarin.Forms Android?
Also does anyone know another way that I could programmatically change the color of the scroll bar.
Upvotes: 1
Views: 2773
Reputation: 9124
Have two style files Light and Dark XAML and ThemeHelper class which switches the themes at run time
Refer this https://github.com/jamesmontemagno/Hanselman.Forms/tree/vnext/src/Hanselman/Styles
As mentioned this sample project has great resources for theme switching.
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestApp.LightTheme">
<Color
x:Key="TextColor">#ababab</Color>
<Color
x:Key="GenericBackground">#e3e3e3</Color>
<Color
x:Key="AppBackground">#FFFFFF</Color>
</ResourceDictionary>
<?xml version="1.0" encoding="UTF-8"?>
<ResourceDictionary
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestApp.DarkTheme">
<Color
x:Key="TextColor">#e3e3e3</Color>
<Color
x:Key="GenericBackground">#ababab</Color>
<Color
x:Key="AppBackground">#000000</Color>
</ResourceDictionary>
public class ThemeHelper
{
public static Theme CurrentTheme = Theme.Light;
public static void ChangeTheme(Theme theme, bool forceTheme = false)
{
// don't change to the same theme
if (theme == CurrentTheme && !forceTheme)
return;
//// clear all the resources
var applicationResourceDictionary = Application.Current.Resources;
ResourceDictionary newTheme;
if (theme == Theme.Default)
{
theme = AppInfo.RequestedTheme == AppTheme.Dark ? Theme.Dark : Theme.Light;
}
switch (theme)
{
case Theme.Light:
newTheme = new LightTheme();
break;
case Theme.Dark:
newTheme = new DarkTheme();
break;
case Theme.Default:
default:
newTheme = new LightTheme();
break;
}
ManuallyCopyThemes(newTheme, applicationResourceDictionary);
CurrentTheme = theme;
var background = (Color)App.Current.Resources["AppBackground"];
}
static void ManuallyCopyThemes(ResourceDictionary fromResource, ResourceDictionary toResource)
{
foreach (var item in fromResource.Keys)
{
toResource[item] = fromResource[item];
}
}
}
public enum Theme
{
Default,
Light,
Dark
}
Before starting the app initialize theme , you can retrieve it from Application settings or from DB like SQLite or API too
public App()
{
InitializeComponent();
ThemeHelper.ChangeTheme(Theme.Default);
MainPage = new NavigationPage(new MainPage());
}
Make sure you use DynamicResource
in this approach
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
BackgroundColor="{DynamicResource AppBackground}"
x:Class="TestApp.MainPage">
<ContentPage.ToolbarItems>
<ToolbarItem
Text="Default"
Clicked="ToolbarItem_Clicked" />
<ToolbarItem
Text="Light"
Clicked="ToolbarItem_Clicked_1" />
<ToolbarItem
Text="Dark"
Clicked="ToolbarItem_Clicked_2" />
</ContentPage.ToolbarItems>
<StackLayout>
<Label
Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
TextColor="{DynamicResource TextColor}"
BackgroundColor="{DynamicResource GenericBackground}" />
<Label
x:Name="label"
TextColor="{DynamicResource TextColor}"
BackgroundColor="{DynamicResource GenericBackground}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
You may still need some changes in Android with respect to different API levels.
Upvotes: 4
Reputation: 806
You can use DynamicResources for implement dynamic theme functionality without redirection. You can follow these documents.
Upvotes: 0