Responder a los cambios de tema del sistema en Xamarin.Forms las aplicaciones

Download Sample Descargar el ejemplo

Los dispositivos suelen incluir temas claros y oscuros, que cada uno hace referencia a un amplio conjunto de preferencias de apariencia que se pueden establecer en el nivel del sistema operativo. Las aplicaciones deben respetar estos temas del sistema y responder inmediatamente cuando cambia el tema del sistema.

El tema del sistema puede cambiar por diversos motivos, según la configuración del dispositivo. Esto incluye el tema del sistema que el usuario cambia explícitamente, cambia debido a la hora del día y cambia debido a factores ambientales como la luz baja.

Xamarin.Forms Las aplicaciones pueden responder a los cambios de tema del sistema mediante el consumo de recursos con la AppThemeBinding extensión de marcado y los SetAppThemeColor métodos de extensión y SetOnAppTheme<T> .

Se deben cumplir los siguientes requisitos para Xamarin.Forms responder a un cambio de tema del sistema:

  • Xamarin.Forms 4.6.0.967 o superior.
  • iOS 13 o superior.
  • Android 10 (API 29) o superior.
  • Compilación 14393 o posterior de UWP.
  • macOS 10.14 o superior.

Las capturas de pantalla siguientes muestran páginas temáticas, para temas del sistema claro y oscuro en iOS y Android:

Screenshot of the main page of a themed app, on iOS and AndroidScreenshot of the detail page of a themed app, on iOS and Android

Definición y consumo de recursos de tema

Los recursos para temas claros y oscuros se pueden consumir con la AppThemeBinding extensión de marcado y los SetAppThemeColor métodos de extensión y SetOnAppTheme<T> . Con estos enfoques, los recursos se aplican automáticamente en función del valor del tema del sistema actual. Además, los objetos que consumen estos recursos se actualizan automáticamente si el tema del sistema cambia mientras se ejecuta una aplicación.

AppThemeBinding (extensión de marcado)

La AppThemeBinding extensión de marcado permite consumir un recurso, como una imagen o un color, en función del tema del sistema actual:

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

En este ejemplo, el color de texto del primero Label se establece en verde cuando el dispositivo usa su tema claro y se establece en rojo cuando el dispositivo usa su tema oscuro. Del mismo modo, Image muestra un archivo de imagen diferente basado en el tema del sistema actual.

Además, los recursos definidos en un ResourceDictionary se pueden consumir con la StaticResource extensión de marcado:

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

En este ejemplo, el color de fondo de Grid y el Button estilo cambia en función de si el dispositivo usa su tema claro o el tema oscuro.

Para obtener más información sobre la AppThemeBinding extensión de marcado, vea Extensión de marcado AppThemeBinding.

Métodos de extensión

Xamarin.Forms incluye SetAppThemeColor y SetOnAppTheme<T> métodos de extensión que permiten VisualElement a los objetos responder a los cambios de tema del sistema.

El SetAppThemeColor método permite Color especificar objetos que se establecerán en una propiedad de destino basada en el tema del sistema actual:

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

En este ejemplo, el color de texto de Label se establece en verde cuando el dispositivo usa su tema claro y se establece en rojo cuando el dispositivo usa su tema oscuro.

El SetOnAppTheme<T> método permite especificar objetos de tipo T que se establecerán en una propiedad de destino basada en el tema del sistema actual:

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

En este ejemplo, se Image muestra lightlogo.png cuando el dispositivo usa su tema claro y darklogo.png cuando el dispositivo usa su tema oscuro.

Detección del tema actual del sistema

El tema del sistema actual se puede detectar obteniendo el valor de la Application.RequestedTheme propiedad :

OSAppTheme currentTheme = Application.Current.RequestedTheme;

La RequestedTheme propiedad devuelve un OSAppTheme miembro de enumeración. La enumeración OSAppTheme define los miembros siguientes:

  • Unspecified, que indica que el dispositivo usa un tema no especificado.
  • Light, que indica que el dispositivo usa su tema claro.
  • Dark, que indica que el dispositivo usa su tema oscuro.

Establecer el tema de usuario actual

El tema usado por la aplicación se puede establecer con la Application.UserAppTheme propiedad , que es de tipo OSAppTheme, independientemente del tema del sistema que esté operativo actualmente:

Application.Current.UserAppTheme = OSAppTheme.Dark;

En este ejemplo, la aplicación se establece para usar el tema definido para el modo oscuro del sistema, independientemente del tema del sistema que esté operativo actualmente.

Nota

Establezca la UserAppTheme propiedad OSAppTheme.Unspecified en como valor predeterminado para el tema del sistema operativo.

React a los cambios de tema

El tema del sistema en un dispositivo puede cambiar por diversos motivos, en función de cómo se configure el dispositivo. Xamarin.Forms Las aplicaciones se pueden notificar cuando cambia el tema del sistema controlando el Application.RequestedThemeChanged evento:

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

El AppThemeChangedEventArgs objeto, que acompaña al RequestedThemeChanged evento, tiene una sola propiedad denominada RequestedTheme, de tipo OSAppTheme. Esta propiedad se puede examinar para detectar el tema del sistema solicitado.

Importante

Para responder a los cambios de tema en Android, debe incluir la ConfigChanges.UiMode marca en el Activity atributo de la MainActivity clase.