Compartilhar via


Responder às alterações de tema do sistema

Procurar amostra. Procurar no exemplo

Os dispositivos normalmente incluem temas claros e escuros, cada um deles se refere a um amplo conjunto de preferências de aparência que podem ser definidas no nível do sistema operacional. Os aplicativos devem respeitar esses temas do sistema e responder imediatamente quando o tema do sistema for alterado.

O tema do sistema pode mudar por vários motivos, dependendo da configuração do dispositivo. Isso inclui o tema do sistema sendo explicitamente alterado pelo usuário, ele mudando devido à hora do dia e ele mudando devido a fatores ambientais, como pouca luz.

Os aplicativos .NET MAUI (.NET Multi-Platform App UI) podem responder às alterações de tema do sistema consumindo recursos com a extensão de marcação AppThemeBinding e os métodos de extensão SetAppThemeColor e SetAppTheme<T>.

Observação

Os aplicativos .NET MAUI podem responder a alterações de tema do sistema no iOS 13 ou superior, Android 10 (API 29) ou superior, macOS 10.14 ou superior e Windows 10 ou superior.

A captura de tela a seguir mostra páginas de temas para o tema claro do sistema no iOS e o tema escuro do sistema no Android:

Captura de tela da página principal de um aplicativo de tema.

Definir e consumir recursos de tema

Recursos de temas claros e escuros podem ser consumidos com a extensão de marcação AppThemeBinding e os métodos de extensão SetAppThemeColor e SetAppTheme<T>. Com essas abordagens, os recursos são aplicados automaticamente com base no valor do tema do sistema atual. Além disso, os objetos que consomem esses recursos são atualizados automaticamente se o tema do sistema for alterado durante a execução de um aplicativo.

Extensão de marcação AppThemeBinding

A extensão de marcação AppThemeBinding permite que você consuma um recurso, como uma imagem ou cor, com base no tema do sistema atual.

A extensão de marcação AppThemeBinding tem o suporte da classe AppThemeBindingExtension, que define as seguintes propriedades:

  • Default, do tipo object, que você definiu como o recurso a ser usado por padrão.
  • Light, do tipo object, que você define como o recurso a ser usado quando o dispositivo estiver usando seu tema claro.
  • Dark, do tipo object, que você define como o recurso a ser usado quando o dispositivo estiver usando seu tema escuro.
  • Value, do tipo object, que retorna o recurso que está sendo usado atualmente pela extensão de marcação.

Observação

O analisador XAML permite que a classe AppThemeBindingExtension seja abreviada como AppThemeBinding.

A propriedade Default é a propriedade de conteúdo de AppThemeBindingExtension. Portanto, nas expressões de marcação XAML expressas com chaves, você pode eliminar a parte Default= da expressão fornecida se ela for o primeiro argumento.

O seguinte exemplo de XAML mostra como usar a extensão de marcação 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>

Neste exemplo, a cor do texto do primeiro Label é definida como verde quando o dispositivo está usando seu tema claro e é definida como vermelho quando o dispositivo está usando seu tema escuro. Da mesma forma, o Image exibe um arquivo de imagem diferente com base no tema do sistema atual.

Os recursos definidos em um ResourceDictionary podem ser consumidos em um AppThemeBinding com a extensão de marcação 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>    

Neste exemplo, a cor da tela de fundo do Grid e o estilo do Button mudam com base no fato de o dispositivo estar usando seu tema claro ou escuro.

Além disso, os recursos definidos em um ResourceDictionary também podem ser consumidos em um AppThemeBinding com a extensão de marcação 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>

Métodos de extensão

O .NET MAUI inclui os métodos de extensão SetAppThemeColor e SetAppTheme<T> que permitem que os objetos VisualElement respondam a alterações de tema do sistema.

O método SetAppThemeColor permite especificar objetos Color que serão definidos em uma propriedade de destino com base no tema do sistema atual:

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

Neste exemplo, a cor do texto do primeiro Label é definida como verde quando o dispositivo está usando seu tema claro e é definida como vermelho quando o dispositivo está usando seu tema escuro.

O método SetAppTheme<T> permite especificar objetos do tipo T que serão definidos em uma propriedade de destino com base no tema do sistema atual:

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

Neste exemplo, o Image exibe lightlogo.png quando o dispositivo está usando seu tema claro e darklogo.png quando o dispositivo está usando seu tema escuro.

Detectar o tema atual do sistema

O tema atual do sistema pode ser detectado obtendo o valor da propriedade Application.RequestedTheme:

AppTheme currentTheme = Application.Current.RequestedTheme;

A propriedade RequestedTheme retorna um membro da enumeração AppTheme. A enumeração AppTheme define os seguintes membros:

  • Unspecified, que indica que o dispositivo está usando um tema não especificado.
  • Light, o que indica que o dispositivo está usando seu tema claro.
  • Dark, o que indica que o dispositivo está usando seu tema escuro.

Definir o tema de usuário atual

O tema usado pelo aplicativo pode ser definido com a propriedade Application.UserAppTheme, que é do tipo AppTheme, independentemente de qual tema do sistema está sendo usado atualmente:

Application.Current.UserAppTheme = AppTheme.Dark;

Neste exemplo, o aplicativo é definido para usar o tema definido para o modo escuro do sistema, independentemente de qual tema do sistema esteja sendo usado no momento.

Observação

Defina a propriedade UserAppTheme como AppTheme.Unspecified como padrão para o tema do sistema operacional.

Reagir às alterações de tema

O tema do sistema em um dispositivo pode mudar por vários motivos, dependendo de como o dispositivo está configurado. Os aplicativos .NET MAUI podem ser notificados quando o tema do sistema é alterado manipulando o evento Application.RequestedThemeChanged:

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

O objeto AppThemeChangedEventArgs, que acompanha o evento RequestedThemeChanged, tem apenas uma propriedade chamada RequestedTheme, do tipo AppTheme. Essa propriedade pode ser analisada para detectar o tema do sistema solicitado.

Importante

Para responder às alterações de tema no Android, sua classe MainActivity deve incluir o sinalizador ConfigChanges.UiMode no atributo Activity. Os aplicativos .NET MAUI criados com os modelos de projeto do Visual Studio incluem automaticamente esse sinalizador.