有两个样式文件 Light 和 Dark XAML 和 ThemeHelper 类,在运行时切换主题
参考这个https://github.com/jamesmontemagno/Hanselman.Forms/tree/vnext/src/Hanselman/Styles
更新
如前所述,此示例项目具有大量用于主题切换的资源。
轻主题
<?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
}
在启动应用程序初始化主题之前,您可以从应用程序设置或 SQLite 或 API 等数据库中检索它
public App()
{
InitializeComponent();
ThemeHelper.ChangeTheme(Theme.Default);
MainPage = new NavigationPage(new MainPage());
}
确保在这种方法中使用DynamicResource
<?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>
截图
您可能仍需要在 Android 中针对不同的 API 级别进行一些更改。
其他参考
Theming
Dark mode detection
Android Dark Theme