Поделиться через


Реагирование на изменения темы системы

Просмотрите пример. Обзор примера

Устройства обычно включают светлые и темные темы, которые относятся к широкому набору настроек внешнего вида, которые можно задать на уровне операционной системы. Приложения должны соблюдать эти системные темы и реагировать немедленно при изменении системной темы.

Системная тема может измениться по различным причинам в зависимости от конфигурации устройства. Это включает в себя явно измененную пользователем системную тему, ее изменение в связи с временем дня и изменение из-за экологических факторов, таких как низкий свет.

Приложения пользовательского интерфейса многоплатформенных приложений .NET (.NET MAUI) могут реагировать на изменения системной темы, используя ресурсы с AppThemeBinding расширением разметки и SetAppThemeColor SetAppTheme<T> методами расширения.

Примечание.

Приложения .NET MAUI могут реагировать на изменения системной темы в iOS 13 или более поздней версии, Android 10 (API 29) или более поздней версии, macOS 10.14 или более поздней версии, а также Windows 10 или более поздней версии.

На следующем снимка экрана показаны тематические страницы для светлой системной темы в iOS и темной системной темы в Android:

Снимок экрана: главная страница тематических приложений.

Определение и использование ресурсов темы

Ресурсы для светлых и темных тем можно использовать с расширением AppThemeBinding разметки и SetAppThemeColor SetAppTheme<T> методами расширения. С помощью этих подходов ресурсы автоматически применяются на основе значения текущей системной темы. Кроме того, объекты, использующие эти ресурсы, автоматически обновляются при изменении системной темы во время выполнения приложения.

Расширение разметки AppThemeBinding

Расширение AppThemeBinding разметки позволяет использовать ресурс, например изображение или цвет, на основе текущей системной темы.

Расширение разметки AppThemeBinding поддерживается классом AppThemeBindingExtension, определяющим следующие свойства:

  • DefaultobjectТип , который вы устанавливаете для ресурса, который будет использоваться по умолчанию.
  • LightobjectТип , который вы устанавливаете для ресурса, который будет использоваться, когда устройство использует его световую тему.
  • DarkobjectТипа, который вы задаете ресурсу, который будет использоваться при использовании устройства темной темы.
  • ValueobjectТип , который возвращает ресурс, который в настоящее время используется расширением разметки.

Примечание.

Средство синтаксического анализа XAML позволяет сократить класс AppThemeBindingExtension как AppThemeBinding.

Свойство Default является свойством содержимого AppThemeBindingExtension. Поэтому для выражений разметки XAML, выраженных с фигурными скобками, можно исключить Default= часть выражения, указанную в первом аргументе.

В следующем примере XAML показано, как использовать расширение разметки AppThemeBinding :

<StackLayout>
    <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>

В этом примере цвет текста первого Label имеет зеленый цвет, если устройство использует его световую тему и имеет красный цвет, если устройство использует темную тему. Аналогичным образом отображается Image другой файл изображения на основе текущей системной темы.

Ресурсы, определенные в объекте ResourceDictionary AppThemeBinding 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 стиля изменяется на основе того, использует ли устройство светлая тема или темная тема.

Кроме того, ресурсы, определенные в объекте, ResourceDictionary также могут использоваться в AppThemeBinding DynamicResource расширении разметки:

<ContentPage ...>
    <ContentPage.Resources>
        <Color x:Key="Primary">DarkGray</Color>
        <Color x:Key="Secondary">HotPink</Color>
        <Color x:Key="Tertiary">Yellow</Color>
        <Style x:Key="labelStyle" TargetType="Label">
            <Setter Property="Padding" Value="5"/>
            <Setter Property="TextColor" Value="{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Primary}}" />
            <Setter Property="BackgroundColor" Value="{AppThemeBinding Light={DynamicResource Primary}, Dark={DynamicResource Secondary}}" />
        </Style>
    </ContentPage.Resources>
    <Label x:Name="myLabel"
           Style="{StaticResource labelStyle}"/>
</ContentPage>

Методы расширения

.NET MAUI включает SetAppThemeColor и SetAppTheme<T> методы расширения, позволяющие VisualElement объектам реагировать на изменения системной темы.

Метод SetAppThemeColor позволяет Color указывать объекты, которые будут заданы в целевом свойстве на основе текущей системной темы:

Label label = new Label();
label.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);

В этом примере для Label цвета текста устанавливается зеленый цвет, если устройство использует его световую тему и имеет красный цвет, если устройство использует свою темную тему.

Метод SetAppTheme<T> позволяет указывать объекты типа T , которые будут заданы в целевом свойстве на основе текущей системной темы:

Image image = new Image();
image.SetAppTheme<FileImageSource>(Image.SourceProperty, "lightlogo.png", "darklogo.png");

В этом примере Image отображается lightlogo.png , когда устройство использует светлую тему и darklogo.png когда устройство использует темную тему.

Определение текущей системной темы

Текущая системная тема может быть обнаружена, получив значение Application.RequestedTheme свойства:

AppTheme currentTheme = Application.Current.RequestedTheme;

Свойство RequestedTheme возвращает AppTheme элемент перечисления. Перечисление AppTheme определяет следующие члены:

  • Unspecified, указывающий, что устройство использует неопределенную тему.
  • Light, указывающее, что устройство использует свою световую тему.
  • Dark, который указывает, что устройство использует свою темную тему.

Настройка текущей темы пользователя

Тема, используемая приложением, может быть задана со свойством Application.UserAppTheme , который имеет тип AppTheme, независимо от того, какая системная тема в настоящее время работает:

Application.Current.UserAppTheme = AppTheme.Dark;

В этом примере приложение использует тему, определенную для системного темного режима, независимо от того, какая системная тема в настоящее время работает.

Примечание.

UserAppTheme Задайте для свойства AppTheme.Unspecified значение по умолчанию для темы операционной системы.

Реагирование на изменения темы

Системная тема на устройстве может меняться по различным причинам в зависимости от того, как настроено устройство. Приложения .NET MAUI можно получать уведомления при изменении системной темы, обрабатывая Application.RequestedThemeChanged событие:

Application.Current.RequestedThemeChanged += (s, a) =>
{
    // Respond to the theme change
};

Объект AppThemeChangedEventArgs , который сопровождает RequestedThemeChanged событие, имеет одно свойство с именем RequestedThemeтипа AppTheme. Это свойство можно проверить для обнаружения запрошенной системной темы.

Внимание

Чтобы реагировать на изменения темы в Android, класс MainActivity должен включать ConfigChanges.UiMode флаг в Activity атрибут. Приложения .NET MAUI, созданные с помощью шаблонов проектов Visual Studio, автоматически включают этот флаг.