[Tips and Tricks] Windows Phone. Optimiza tus Apps a pantallas grandes

Novedades de la actualización Update 3

Desde hace unas semanas ya tenemos disponible la actualización Update 3 (también conocida previamente como GDR3). Entre el listado de mejoras incluidas contamos con:

  • Más grande. Se suprime el límite de tamaño en resolución establecido permitiendo la llegada en el futuro de teléfonos con pantallas de 5 o 6 pulgadas con resolución de 1080p (1080 × 1920).
  • Más potencia. La actualización permite también utilizar los procesadores de cuatro núcleos de Qualcomm.
  • Mayor personalización. La actualización permite asignar tonos diferentes a diferentes Apps como mensajes, correos, recordatorios, alarmas, etc.
  • Mayor control. Podemos controlar que Apps se ejecutan en Background y ahora además podemos cerrarlas.
  • Más accesible. Se realiza un esfuerzo por facilitar el uso del dispositivo a personas invidentes. Se permite la gestión de llamadas, correos, contactos, uso de Skype o Lync, etc.

Nuevos dispositivos llegan…

El pasado 22 de Octubre Nokia presentaba en Abu Dhabi su primera flamante tablet, el Lumia 2520. También desvelaba dos nuevos smartphones de pantalla grande los Lumia 1520 y 1320:

Phablets

Phablets

Con los dispositivos recién anunciados por Nokia se aumenta el rango de posibilidades en resoluciones y aspect ratio. El Nokia Lumia 1520 cuenta con una resolución de 1080x1920px y el Nokia Lumia 1320 cuenta con una resolución de 720x1280px, ambos con una pantalla de 6 pulgadas y 16:9 de aspect ratio.

Esto abre un nuevo debate a los desarrolladores, ¿cómo preparo mis Apps para sacar el máximo provecho en este tipo de dispositivos?

Impacto en Apps existentes

Aplicaciones Windows Phone 8

En el archivo de manifiesto vienen incluidas las resoluciones que soportará nuestra Aplicación:

<ScreenResolutions>
     <ScreenResolution Name="ID_RESOLUTION_WVGA"/>
     <ScreenResolution Name="ID_RESOLUTION_WXGA"/>
     <ScreenResolution Name="ID_RESOLUTION_HD720P"/>
</ScreenResolutions>

La resolución 1080p no se distingue de los 720p, por lo tanto, si nuestra Aplicación soporta 720p (ID_RESOLUTION_HD720P) funcionará en dispositivos 1080p.

App WP8 soportando 720p en 1080p

App WP8 soportando 720p en 1080p

NOTA: Si tu Aplicación Windows Phone 8 no soporta 720p tampoco estará disponible para dispositivos 1020p.

Aplicaciones Windows Phone 7

Las Aplicaciones Windows Phone 7 funcionaran sin problemas en dispositivos con la actualización Update 3 y con un aspect ratio de 16:9. Sin embargo, y dado que estas Aplicaciones se crearon con un aspect ratio de 15:9, no se reescalaran correctamente dejando una banda negra en la parte superior de la pantalla.

App WP7 en 1080p

App WP7 en 1080p

Optimizando Apps a pantallas grandes

Como ya hemos comentado, contamos con una nueva resolución. Sin duda, para poder ofrecer a nuestros usuarios la mejor experiencia posible en cualquiera de las resoluciones disponibles, necesitamos identificar cada una de ellas, la nueva resolución de 1080p incluida:

Nueva resolución

Sin embargo, entre las resoluciones 720p y 1080p no podemos encontrar diferencias utilizando la propiedad App.Current.Host.Content.ScaleFactor o Application.Current.Host.Content.ActualHeight ya que en ambas devuelven los mismos resultados, 150 y 853 respectivamente.

¿Cómo diferenciar entonces entre un dispositivo 720p y otro 1080p?

Microsoft nos facilita una nueva clase DeviceExtendedProperties que nos facilita información relacionada con la resolución. Las nuevas propiedades son:

  • PhysicalScreenResolution: Variable de tipo Size, nos devuelve el ancho y alto de la pantalla en pixeles.
  • RawDpiX: Variable de tipo double, devuelve los DPI del horizontal de la pantalla.
  • RawDpiY: Variable de tipo double, devuelve los DPI del vertical de la pantalla.

Podremos detectar si estamos ante un dispositivo 1080p de la siguiente forma:

static private double _screenSize = -1.0f;
static private double _screenDpiX = 0.0f;
static private double _screenDpiY = 0.0f;
static private Size _resolution;

try
{
     _screenDpiX = (double)DeviceExtendedProperties.GetValue("RawDpiX");
     _screenDpiY = (double)DeviceExtendedProperties.GetValue("RawDpiY");
     _resolution = (Size)DeviceExtendedProperties.GetValue("PhysicalScreenResolution");

     _screenSize = Math.Sqrt(Math.Pow(_resolution.Width / _screenDpiX, 2) +
                   Math.Pow(_resolution.Height / _screenDpiY, 2));
}
catch (Exception e)
{
     _screenSize = 0;
}

return (_screenSize >= 6.0f);

Detectado cuando estamos ante las nuevas pantallas de 6″ de los nuevos dispositivos que llegarán como el Nokia Lumia 1520 o el Nokia Lumia 1320 nos permite adaptar dinamicamente el layout de nuestra Aplicación para aprovechar de la mejor manera posible cada dispositivo.

¿Cómo?

Bien, como solemos hacer, vamos a crear una Aplicación de ejemplo para ello:

Nuevo proyecto

Vamos a crear un listado tipo album que adaptaremos segun el tipo de resolución. En dispositivos WVGA y WXGA mostraremos dos columnas mientras que en dispositivos 720p y 1020p mostraremos una columna más de una forma similar a como el propio sistema muestra una columna más de tiles.

Comenzamos centrándonos en la interfaz de la Aplicación, añadimos el listado donde mostrar todas las fotos del album:

<phone:LongListSelector>
</phone:LongListSelector>

Definimos el template de cada elemento del listado:

<DataTemplate>
     <Grid Margin="10, 5">
     <Grid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="Auto" />
     </Grid.RowDefinitions>
     <Image Grid.Row="0" Source="{Binding Image}" Style="{StaticResource GridImage}" />
     <TextBlock Grid.Row="1" Margin="0" Text="{Binding Title}" />
</Grid>
</DataTemplate>

Necesitamos datos para poder probar… vamos a darle solución. Crearemos una viewmodel para nuestra vista donde obtendremos un listado de elementos.

Antes de crear la viewmodel, definiremos el modelo, cada elemento del album:

public class Item
{
     public string Title { get; set; }
     public string Image { get; set; }
}

A continuación, en nuestro viewmodel crearemos una colección de elementos:

private ObservableCollection<Item> _items;

public ObservableCollection<Item> Items
{
     get
     {
          return _items;
     }
}

Creamos un método LoadData donde se creará un listado de datos que para este ejemplo será el listado de juegos de la inminente Xbox One:

private void LoadData()
{
_items = new ObservableCollection<Item>
{
new Item
{
     Title = "Forza Motorsport 5",
     Image = "http://compass.xboxlive.com/assets/cd/33/cd33e4ec-5406-40d4-8129-b92504e877d3.jpg?n=Forza%205.jpg"
},
new Item
{
     Title = "Ryse: Son of Rome",
     Image = "http://compass.xboxlive.com/assets/4a/8c/4a8cc02a-ed1a-432f-9fbd-42de90a4525e.jpg?n=Ryse.jpg"
},
new Item
{
     Title = "Kinect Sports Rivals",
     Image = "http://compass.xboxlive.com/assets/95/1e/951e1851-a32b-4738-903a-ed58839cb0bc.jpg?n=KinectSportsRivals.jpg"
},
new Item
{
     Title = "Dead Rising 3",
     Image = "http://compass.xboxlive.com/assets/bd/83/bd835a75-d7be-4134-b7c7-b9730f8b3dde.jpg?n=DeadRising3_hubhero.jpg"
},
new Item
{
     Title = "Halo para Xbox One",
     Image = "http://compass.xboxlive.com/assets/17/69/1769a7af-4a9a-4b23-9ef7-ddb9dbdc10a3.jpg?n=HaloXboxOne-200x190.jpg"
},
new Item
{
     Title = "Sunset Overdrive",
     Image = "http://compass.xboxlive.com/assets/f9/60/f9606a94-2318-4b8a-87b1-a387cfe96661.jpg?n=SunsetOverdrive.jpg"
},
new Item
{
     Title = "Quantum Break",
     Image = "http://compass.xboxlive.com/assets/97/16/9716a7e4-62ed-403b-a2de-19aa9e34445a.jpg?n=Quantum%20Break.jpg"
},
new Item
{
     Title = "Killer Instinct",
     Image = "http://compass.xboxlive.com/assets/07/1c/071c4e77-273e-45e2-84fd-2a0006eb582a.png?n=KillerInstinct200x190.png"
},
new Item
{
     Title = "Project: Spark",
     Image = "http://compass.xboxlive.com/assets/ab/bf/abbfc373-38e0-4fe6-88a1-3d325ff571d0.png?n=ProjectSpark_banner_tree_200x190.png"
},
new Item
{
     Title = "Zoo Tycoon",
     Image = "http://compass.xboxlive.com/assets/fb/df/fbdfa0e9-fc9b-4c38-a512-f6fb421e4924.jpg?n=Zoo_Tycoon_200x190.jpg"
},
new Item
{
     Title = "Titanfall",
     Image = "http://compass.xbox.com/assets/8f/db/8fdb6276-3d2e-49e5-9ba6-76082d63e715.jpg?n=hero-titanfall-metro-200x190.jpg"
},
new Item
{
     Title = "Call of Duty: Ghosts",
     Image = "http://compass.xboxlive.com/assets/c7/b9/c7b96d97-d1f7-4ffe-9d52-a29298383e3f.jpg?n=COD_Ghosts.jpg"
}
};

Cargamos los datos desde el constructor:

public MainViewModel()
{
     LoadData();
}

Creamos un estilo por defecto que se utilizará en nuestra Aplicación. En este archivo de recursos crearemos los estilos a usar por defecto, en nuestro ejemplo, el estilo por defecto del listado:

 <Style x:Key="ListStyle" TargetType="phone:LongListSelector">
     <Setter Property="GridCellSize" Value="140, 140" />
</Style>

Añadimos el archivo de recursos en nuestro App.xaml:

<ResourceDictionary>
     <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="Themes/DefaultStyles.xaml" />
     </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Asignamos el estilo correspondiente al listado:

Style="{StaticResource ListStyle}"

Todo listo!. Si ejecutamos nuestra Aplicación obtendremos el siguiente resultado:

Nuestra App

Nuestra App

Pinta bien, aunque… podemos mejorar la experiencia de uso segun el dispositivo!

Crearemos otro archivo de recursos destinado a sobrescribir el utilizado por defecto en dispositivos con pantallas grandes. En este archivo de recursos definimos el estilo a usar en nuestra lista album:

<Style x:Key="ListStyle" TargetType="phone:LongListSelector">
     <Setter Property="GridCellSize" Value="140, 140" />
</Style>

Nos crearemos un helper que utilizaremos para detectar si estamos ante un dispositivo 1080p (tal y como vimos previamente) para cargar dinámicamente el archivo de recursos destinado a pantallas grandes y sobrescribir el layout:

public static void Set1080PTheme()
{
     if (ResolutionHelper.Is1080P)
     {
         var the1080PTheme = new ResourceDictionary
         {
             Source = new Uri("/EjemploResolucion;component/Themes/HDStyles.xaml", UriKind.RelativeOrAbsolute)
         };

         Application.Current.Resources.MergedDictionaries.Add(the1080PTheme);
     }
}

Lo llamaremos al inicio de nuestra Aplicación en el App.xaml.cs:

ThemeSelector.Set1080PTheme();

Y el resultado es el siguiente:

Aprovechamos el espacio mejor!

Aprovechamos el espacio mejor!

Podéis descargar el ejemplo realizado en el siguiente enlace:

NOTA: Es importante recordar que con el Update 3 no hemos recibido un nuevo SDK. Tendremos emulador de 1080p proximamente pero por ahora probaremos usando los emuladores actuales, en concreto, el emulador 720p. Nokia pondrá en su servicio Remote Device Access dispositivos 1080p a disposición de los desarrolladores.

Otros detalles

Tenemos otro listado de puntos importantes en los cuales centrar nuestra atención con el objetivo de preparar la Aplicación a cualquier resolución:

  • SplashScreen: Para poder utilizar una SplashScreen en dispositivos 1020p debemos utilizar una imagen llamada SplashScreenImage.Screen-720p.jpg. Para que se visualice correctamente la imagen debe ser de 720x1280px. La imagen se escalara en dispositivos 1080p para ocupar la pantalla completa. Si queremos evitar este escalado debemos utilizar una imagen de 1080x920px. En este caso, en 1080p no se realizaría ningun escalado pero si se reduciría en dispositivos 720p.
  • Uso de imágenes a mayor resolución. Es recomendable utilizar recursos preparados para 1080p y dejar al sistema escalar la imagen a resoluciones menores como 720p en caso necesario.
  • Mayor uso de memoria. Con una pantalla mayor y mejor resolución como hemos visto se tiende a utilizar recursos de mayor calidad, lo que provoca también un mayor consumo de memoria. Recordar que podemos solicitar un mayor consumo de memoria utilizando la etiqueta ID_FUNCCAP_EXTEND_MEM en el archivo de manifiesto. Más información en el siguiente enlace.

Más Información

Un pensamiento en “[Tips and Tricks] Windows Phone. Optimiza tus Apps a pantallas grandes

  1. Pingback: Tips & Tricks de desarrollo para Windows Phone - MSDN España - Site Home - MSDN Blogs

Deja un comentario