Valores específicos de la plataforma en XAML

Completado

La experiencia visual de la aplicación será diferente en cada plataforma. A menudo, tendrá que ajustar la interfaz de usuario para cada plataforma en función de los elementos visuales que use. .NET MAUI permite administrar el diseño de la aplicación en función de estas propiedades de dispositivo.

En esta unidad, obtendrá información sobre las características que proporciona .NET MAUI para permitirle retocar la interfaz de usuario de sus aplicaciones según la plataforma en la que se ejecuten.

Uso de la clase Device

DeviceInfo es una clase de utilidad que proporciona información específica del dispositivo para el dispositivo en el que se ejecuta la aplicación. Expone esta información mediante un conjunto de propiedades. La propiedad más importante es DeviceInfo.Platform, que devuelve una cadena que indica el tipo de dispositivo actualmente en uso: Android, iOS, WinUI o macOS.

Considere el escenario siguiente como ejemplo de cuándo podría usar esta característica. El comportamiento predeterminado en una aplicación iOS de .NET MAUI es que el contenido agregado a una página invade la barra de estado de iOS en la parte superior de la pantalla. Este comportamiento lo quiere cambiar. La solución más sencilla es desplazar el contenido hacia abajo en la página. La solución Notas que creó en el ejercicio anterior soluciona este problema estableciendo la propiedad Padding del control VerticalStackLayout para mover el contenido hacia abajo en 60 puntos:

<VerticalStackLayout x:Name="MyStackLayout" Padding="30,60,30,30">
    ...
</VerticalStackLayout>

La cuestión es que este problema solo se aplica en iOS. Como el contenido se desplaza tanto hacia abajo en Android y WinUI, se genera un desperdicio del espacio real en pantalla en la parte superior de la página.

Puede consultar la propiedad DeviceInfo.Platform para resolver este problema de visualización. Puede agregar el código siguiente al constructor de páginas de la aplicación para expandir el relleno en la parte superior de la página, pero solo para iOS:

MyStackLayout.Padding = 
    DeviceInfo.Platform == DevicePlatform.iOS
        ? new Thickness(30, 60, 30, 30) // Shift down by 60 points on iOS only
        : new Thickness(30); // Set the default margin to be 30 points

Nota:

Estructura de DevicePlatform.iOS is a DevicePlatform que devuelve el valor de cadena iOS. Hay propiedades equivalentes para las otras plataformas compatibles. Debe usar estas propiedades en lugar de comparar con cadenas codificadas de forma rígida; es una buena práctica y prueba la resistencia del código si algunos de estos valores de cadena cambian en el futuro.

Este código funciona, pero está en el archivo de código subyacente de la página. El relleno es un valor específico de la interfaz de usuario. Posiblemente resulta más adecuado y cómodo hacerlo desde XAML en lugar de desde el código subyacente.

Uso de la extensión de marcado OnPlatform

XAML de .NET MAUI proporciona la extensión de marcado OnPlatform, que permite detectar la plataforma en tiempo de ejecución desde dentro del código XAML. Puede aplicar esta extensión de marcado como parte del código XAML que establece un valor de propiedad. La extensión requiere que proporcione el tipo de la propiedad, junto con una serie de bloques On Platform en los que se establece el valor de la propiedad según la plataforma.

Nota:

La extensión de marcado OnPlatform es genérica; toma un parámetro de tipo. El tipo que especifica el atributo TypeArguments garantiza que se usa el tipo de extensión correcto.

Puede establecer la propiedad Padding de esta forma. Tenga en cuenta que el tipo de la propiedad Padding es Thickness:

<VerticalStackLayout>
    <VerticalStackLayout.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="30,60,30,30" />
        </OnPlatform>
    </VerticalStackLayout.Padding>
    <!--XAML for other controls goes here -->
    ...
</VerticalStackLayout>

Para las plataformas que no sean iOS, el relleno permanecerá establecido en su valor predeterminado de "0,0,0,0". En WinUI y Android, puede establecer el relleno en 30 puntos con bloques OnPlatform adicionales:

<VerticalStackLayout>
    <VerticalStackLayout.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="30,60,30,30" />
            <On Platform="Android" Value="30" />
            <On Platform="WinUI" Value="30" />
        </OnPlatform>
    </VerticalStackLayout.Padding>
    ...
</VerticalStackLayout>

Puede aplicar esta misma técnica a otras propiedades. En el ejemplo siguiente se cambia el color de fondo del diseño de pila en una página a plata en iOS, a verde en Android y a amarillo en Windows.

<VerticalStackLayout>
    ...
    <VerticalStackLayout.BackgroundColor>
        <OnPlatform x:TypeArguments="Color">
            <On Platform="iOS" Value="Silver" />
            <On Platform="Android" Value="Green" />
            <On Platform="WinUI" Value="Yellow" />
        </OnPlatform>
    </VerticalStackLayout.BackgroundColor>
    ...
</VerticalStackLayout>

Esta sintaxis es un poco detallada, pero hay una sintaxis reducida disponible para la extensión OnPlatform. Puede simplificar el ejemplo que establece el relleno de la siguiente manera:

<VerticalStackLayout Padding="{OnPlatform iOS='30,60,30,30', Default='30'}">
    <!--XAML for other controls goes here -->
</VerticalStackLayout>

Puede especificar un valor predeterminado para una propiedad, junto con cualquier valor específico de la plataforma. En este formulario, se deduce el parámetro de tipo de la propiedad a la que se aplica el atributo OnPlatform.

Para establecer el color de fondo, puede usar este fragmento XAML en lugar del segundo ejemplo anterior:

<VerticalStackLayout BackgroundColor="{OnPlatform WinUI=Yellow, iOS=Silver, Android=Green}">
    ...
</VerticalStackLayout>

Comprobación de conocimiento

1.

¿Qué extensión de marcado puede usar en el código XAML para detectar la plataforma en la que se ejecuta la aplicación?

2.

¿Cuál es el propósito del atributo TypeArguments para la extensiónOnPlatform?