Consejos para desarrollar una aplicación con diseño adaptable en Power Apps

  • 14 Sep 2023
  • Power Apps

Desde siempre me pareció un poco triste que Power Apps nos preguntara sobre el dispositivo donde usaríamos la aplicación. Tablet o Teléfono? Sobre todo sabiendo que el cliente más utilizado sería el mismísimo navegador que tenemos en frente. Además, el hecho de que funciones como SaveData estén disponibles solo en mobile hacía solo que la tristeza fuese aún más profunda. Por suerte, hubo grandes progresos en los últimos 2 - 3 años como por ejemplo, el agregado de controles como Container y Layout. En este artículo expongo como resolver algunas dificultades sobre como lograr que una aplicacón desarrollada en Power Apps pueda seguir siendo útil sin importar donde se use.

Configuración de la aplicación

Para poder trabajar en una aplicación para sea capaz de adaptarse a la pantalla del cliente, tendremos que deshabilitar la opción Scale to fit en la sección Display dentro Settings. Seguramente nos converrá deshbailitar también la opción look orientation.

Configuración de dimensiones en Power Apps

El uso de objetos y variables en el diseño adaptable

Power Apps nos da a disposición algunas variables que nos permiten conocer información ya sea de la aplicación que del cliente que la está ejecutando.

  • App.DesignWidth:
    Ancho de la aplicación. Este es el valor cargado en Settings → Display
  • App.DesignHeight:
    Altura de la aplicación. Este es el valor cargado en Settings → Display
  • App.Width:
    El ancho de la pantalla del cliente.
  • App.Height:
    La altura de la pantalla del cliente.
  • App.ActiveScreen.Size: 
    Esta variable devuelve un numero entero del 1 al 4 que representa los puntos de quiebre (breakpoints). Estos puntos de quiebre son configurados en el parámetro SizeBreakpoints dentro App.

Controles para un layout adaptable

Los controles que vamos a usar para desarrollar el layout seran los siguientes:

  • Canvas
  • DataCard
  • Horizontal container
  • Vertical container

Para agregar los controles Canvas y DataCard será necesario agregar una nueva pantalla seleccionando Templates → Scrollable. Generalmente tengo siempre una pantalla como template para simplemente copiar y pegar el camponente Canvas cada vez que lo necesito. El hecho de usar canvas y no directamente los contenedores para todo es que cuando tenemos muchos controles dentro un horizontal container se vuelve inmanejable. En cambio, con el control canvas es posible desplazarse y seleccionar cada control sin problemas.

Dos columnas que se adapten a una

Imaginemos un layout con dos columnas. La de la izquierda más pequeña que la de la derecha. Digamos un 25% - 75%. Ambas columnas vamos a realizarlas dentro de un vertical container que a su vez estará contenido por un horizontal container. Todo dentro el combo canvas - datacard. Los controles estarán dispuestos de la siguiente manera:

  • Canvas
    • DataCard
      • Horizontal container
        • Vertical container (columna izquierda)
        • Vertical container (columna derecha)

La idea será modificar ciertos parámetros utilizando App.ActiveScreen.Size para que cuando sea igual a 1 (mobile) ambas columnas se posicionen una debajo de la otra. Para que esto suceda, sará necesario que:

  1. Ambas columnas tengan un ancho del 100% (Parent.Width).
  2. La altura de las columnas deberá ser igual a la altura total de los controles que contengan. Para esto, podemos crear un control label vacío (lo llamaremos por ejemplo lblFormEnd) ubicado por debajo del resto. Entonces, la altura de la columna será igual a la suma de la posición vertical de la etiqueta más su altura (lblFormEnd.Y + lblFormEnd.Height)
  3. El parámetro AlignInContainer de las columnas en Start.
  4. El parámetro LayoutWrap del horizontal container en true.
  5. El parámetro LayoutOverflowY del horizontal container en scroll ya que su altura será igual a su padre (100% de la App)

En detalle la configuración de cada parámetro de cada control será la siguiente:

  • Horizontal container
    • Height: Parent.Height
    • FillPortions: 0
    • LayoutAlignItems: Start
    • LayoutDirection: Horizontal
    • LayoutJustifyContent: Start
    • LayoutOverflowX: Hide
    • LayoutOverflowY: Scroll
    • LayoutWrap: App.ActiveScreen.Size = 1
    • Width: Parent.Width
      • Vertical container (columna derecha)
        • AlignInContainer: Start
        • FillPortions: 0
        • Height: If(App.ActiveScreen.Size=1,lblEnd.Y+lblEnd.Height, Parent .Height)
        • LayoutJustifyContent: Start
        • LayoutAlignItems: Start
        • Width: If(App.ActiveScreen.Size=1, Parent .Width,375)
      • Vertical container (columna izquierda)
        • AlignInContainer: Start
        • FillPortions: 0
        • Height: If(App.ActiveScreen.Size=1,lblEnd.Y + lblEnd.Height, Parent .Height)
        • LayoutJustifyContent: Start
        • LayoutAlignItems: Start
        • Width: If(App.ActiveScreen.Size=1, Parent .Width, Parent .Width - Vertical container.Width)

El parámetro LayoutWrap del contenedor horizontal es fundamental para hacer que la columna derecha se posicione por debajo de la columna izquierda.

Cómo manejar tablas o galleries muy anchas en mobile

En el caso de Galleries muy anchas mi consejo es el de no adaptarlas. Sobre todo si nuestros usuarios utilizan la mayor parte el tiempo la aplicación en el navegador del portatil o desktop. Si ya se acostumbraron a ver los campos y botones de una galería, mejor no crear dos versiones de la misma cosa. Lo que podemos hacer fácilmente en Power Apps es colocar la Gallery dentro un horizontal container con un scroll horizontal. Debemos tener en cuenta que:

  • El ancho de la Gallery debe tener un valor mínimo que en mobile será obviamente mayor que el ancho de la aplicación.
  • El ancho del contenedor será como máximo el ancho de la aplicación.
  • Debemos configurar el parámetro LayoutOverflowY del contenedor en scroll.
  • Los parámetros LayoutJustifyContent. LayoutAlignItems y AlignInContainer deben configurarse en Start.

El resultado es exactamente igual a una tabla con la clase table-responsive en Bootstrap.