Реагирование на изменения системной темы в 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
другой файл изображения на основе текущей системной темы.
Кроме того, ресурсы, определенные в объекте ResourceDictionary
, можно использовать с расширением StaticResource
разметки:
<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
значение по умолчанию для темы операционной системы.
Реагирование на изменения темы
Системная тема на устройстве может меняться по различным причинам в зависимости от того, как настроено устройство. Xamarin.Forms приложения могут получать уведомления при изменении системной темы, обрабатывая Application.RequestedThemeChanged
событие:
Application.Current.RequestedThemeChanged += (s, a) =>
{
// Respond to the theme change
};
Объект AppThemeChangedEventArgs
, который сопровождает RequestedThemeChanged
событие, имеет одно свойство с именем RequestedTheme
типа OSAppTheme
. Это свойство можно проверить для обнаружения запрошенной системной темы.
Внимание
Чтобы реагировать на изменения темы в Android, необходимо включить ConfigChanges.UiMode
флаг в Activity
атрибут класса MainActivity
.