Реагирование на изменения системной темы в 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:

Снимок экрана: главная страница тематических приложений в iOS и AndroidСнимок экрана: страница сведений о тематических приложениях в 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 .