响应 Xamarin.Forms 应用程序中的系统主题更改
设备通常包含浅色主题和深色主题,每个主题都是指可以在操作系统级别设置的一组广泛的外观首选项。 应用程序应该遵循这些系统主题,并在系统主题发生更改时立即做出响应。
系统主题可能会因各种原因而更改,具体因设备配置而定。 这包括用户以显式方式更改系统主题,基于一天中的时间而更改,以及根据环境因素(如低亮度)而更改。
Xamarin.Forms 应用程序可以通过使用 AppThemeBinding
标记扩展以及 SetAppThemeColor
和 SetOnAppTheme<T>
扩展方法使用资源来响应系统主题更改。
必须满足 Xamarin.Forms 的以下要求才能响应系统主题更改:
- Xamarin.Forms 4.6.0.967 或更高版本。
- iOS 13 或更高版本。
- Android 10 (API 29) 或更高版本。
- UWP 内部版本 14393 或更高版本。
- macOS 10.14 或更高版本。
以下屏幕截图显示了 iOS 和 Android 上的浅色和深色系统主题的主题页:
定义和使用主题资源
可以使用 AppThemeBinding
标记扩展以及 SetAppThemeColor
和 SetOnAppTheme<T>
扩展方法来使用浅色和深色主题的资源。 通过这些方法,可以根据当前系统主题的值自动应用资源。 此外,如果在应用运行时系统主题发生更改,则使用这些资源的对象会自动更新。
AppThemeBinding 标记扩展
AppThemeBinding
标记扩展使你能够根据当前系统主题使用资源,例如图像或颜色:
<ContentPage ...>
<StackLayout Margin="20">
<Label Text="This text is green in light mode, and red in dark mode."
TextColor="{AppThemeBinding Light=Green, Dark=Red}" />
<Image Source="{AppThemeBinding Light=lightlogo.png, Dark=darklogo.png}" />
</StackLayout>
</ContentPage>
在此示例中,当设备使用其浅色主题时,Label
的文本颜色被设置为绿色,当设备使用其深色主题时,文本颜色被设置为红色。 同样,Image
可根据当前系统主题显示不同的图像文件。
此外,可以通过 StaticResource
标记扩展使用 ResourceDictionary
中定义的资源:
<ContentPage ...>
<ContentPage.Resources>
<!-- Light colors -->
<Color x:Key="LightPrimaryColor">WhiteSmoke</Color>
<Color x:Key="LightSecondaryColor">Black</Color>
<!-- Dark colors -->
<Color x:Key="DarkPrimaryColor">Teal</Color>
<Color x:Key="DarkSecondaryColor">White</Color>
<Style x:Key="ButtonStyle"
TargetType="Button">
<Setter Property="BackgroundColor"
Value="{AppThemeBinding Light={StaticResource LightPrimaryColor}, Dark={StaticResource DarkPrimaryColor}}" />
<Setter Property="TextColor"
Value="{AppThemeBinding Light={StaticResource LightSecondaryColor}, Dark={StaticResource DarkSecondaryColor}}" />
</Style>
</ContentPage.Resources>
<Grid BackgroundColor="{AppThemeBinding Light={StaticResource LightPrimaryColor}, Dark={StaticResource DarkPrimaryColor}}">
<Button Text="MORE INFO"
Style="{StaticResource ButtonStyle}" />
</Grid>
</ContentPage>
在此示例中,Grid
和 Button
样式的背景颜色会根据设备使用的是浅色主题还是深色主题而改变。
有关 AppThemeBinding
标记扩展的详细信息,请参阅 AppThemeBinding 标记扩展。
扩展方法
Xamarin.Forms 包括 SetAppThemeColor
和 SetOnAppTheme<T>
扩展方法,使 VisualElement
对象能够响应系统主题更改。
SetAppThemeColor
方法允许指定 Color
对象,将基于当前系统主题在目标属性上设置这些对象:
Label label = new Label();
label.SetAppThemeColor(Label.TextColorProperty, Color.Green, Color.Red);
在此示例中,当设备使用其浅色主题时,Label
的文本颜色被设置为绿色,当设备使用其深色主题时,文本颜色被设置为红色。
SetOnAppTheme<T>
方法允许指定 T
对象,将基于当前系统主题在目标属性上设置这些对象:
Image image = new Image();
image.SetOnAppTheme<FileImageSource>(Image.SourceProperty, "lightlogo.png", "darklogo.png");
在此示例中,当设备使用其浅色主题时,Image
显示 lightlogo.png
,而当设备使用其深色主题时,显示 darklogo.png
。
检测当前系统主题
可以通过获取 Application.RequestedTheme
属性的值来检测当前系统主题:
OSAppTheme currentTheme = Application.Current.RequestedTheme;
RequestedTheme
属性将返回 OSAppTheme
枚举成员。 OSAppTheme
枚举定义以下成员:
Unspecified
指示设备正在使用未指定的主题。Light
指示设备正在使用其浅色主题。Dark
指示设备正在使用其深色主题。
设置当前用户主题
应用程序使用的主题可以通过 Application.UserAppTheme
属性进行设置,该属性的类型为 OSAppTheme
,无论当前运行的是哪个系统主题:
Application.Current.UserAppTheme = OSAppTheme.Dark;
在此示例中,应用程序设置为使用为系统深色模式定义的主题,无论当前运行哪个系统主题。
注意
将 UserAppTheme
属性设置为 OSAppTheme.Unspecified
,以默认使用可运行的系统主题。
对主题更改作出响应
设备上的系统主题可能会因各种原因而发生更改,具体取决于设备的配置方式。 通过处理 Application.RequestedThemeChanged
事件,系统主题更改时可以通知 Xamarin.Forms 应用:
Application.Current.RequestedThemeChanged += (s, a) =>
{
// Respond to the theme change
};
RequestedThemeChanged
事件附带的 AppThemeChangedEventArgs
对象有一个名为 RequestedTheme
的属性,其类型为 OSAppTheme
。 可以检查此属性,以检测请求的系统主题。
重要
若要响应 Android 上的主题更改,必须在 MainActivity
类的 Activity
属性中包含 ConfigChanges.UiMode
标志。