Cómo desarrollar interfaces de usuario receptivas con React Native - 1x03

Esta historia es parte de una serie en la que comparto mis experiencias en React Native: cómo me acerqué y trabajé con componentes RN, API, paquetes externos y todo tipo de problemas. Espero que esta serie de publicaciones resulte útil para la comunidad React Native y proporcione información útil.

EDITAR: El código explicado aquí está disponible como una solución completa a través de un paquete gratuito de código abierto llamado react-native-responsive-screen. ¡Compruébalo y descubre lo fácil que es usarlo! Feliz codificación :-)

¿Qué pasa con la interfaz de usuario receptiva?

¡La interfaz de usuario receptiva es importante! Ningún desarrollador de UI puede negar eso, mientras que la mayoría de nosotros hemos tenido problemas en algún momento para ofrecer uno. Como desarrollador de React Native ahora, debe entregar el mismo resultado o un resultado muy similar para muchas pantallas móviles y tabletas de diferentes tamaños, análisis, factor de escala, densidad de píxeles, etc.

Imagen 1: Cómo se ve una IU receptiva en múltiples dispositivos

Cuando comencé a codificar con RN recuerdo haber pensado:

Tiene que haber un mecanismo interno del marco para abordar la capacidad de respuesta; si no, en el peor de los casos, usaré porcentajes en todas partes ...

Sin embargo, ambas hipótesis estaban equivocadas ... Y lo descubrí por las malas cuando comencé a desarrollar mi primera interfaz de usuario.

El valor de porcentaje de CSS NO es totalmente compatible

Aunque esto ha mejorado mucho desde hace más de 1 año, sigue siendo el caso. Hay propiedades CSS que no admiten valores porcentuales en RN, aunque sí lo hacen en el desarrollo web "normal". Por mencionar algunos: margen, ancho de borde y radio de borde. Y si alguien intenta establecer un valor porcentual, RN lo ignorará por completo o la aplicación se bloqueará.

Se están realizando mejoras y se agrega soporte a medida que pasa el tiempo. Sin embargo, esperar que el marco se ponga al día es prohibitivo para las personas que ya trabajan con React Native en aplicaciones de producción. Quédese conmigo para analizar más a fondo algunos mecanismos RN, cómo nuestro equipo encontró una solución y un ejemplo real de nuestro trabajo.

Reaccionar píxeles nativos e independientes

Al codificar un valor CSS en "píxeles" en React Native, en realidad son píxeles independientes (dp o dpi) y no píxeles de pantalla. Es una unidad de medida diferente (probablemente inspirada en su uso en el desarrollo de Android) que RN usa internamente.

Echemos un vistazo al siguiente código (utilizamos el paquete de componentes con estilo y la sintaxis en lugar de acceder directamente al componente RN StyleSheet):

const HeaderText = styled.Text`
  relleno superior: 20;
  tamaño de fuente: 15;
  Familia tipográfica: Kano;
  ancho: 100%;
  alinear texto: centro;
`;

Puede ver que ambas propiedades padding-top y font-size están escritas como números simples y no hay sufijo px al lado de ellas. Para encontrar los píxeles reales de la pantalla, podemos usar la siguiente ecuación:

px = dp * scaleFactor

Para obtener más información, puede consultar la guía de Android para densidades de píxeles aquí, la descripción general de compatibilidad de pantalla de Android y la guía de paintcodeapp para resoluciones de iPhone.

Alguien podría pensar aquí que podemos usar píxeles independientes en todas partes y obtener la interfaz de usuario receptiva que estamos buscando. Desafortunadamente, ese no es el caso porque scaleFactor depende de la densidad de píxeles. Dicho esto, podríamos desarrollar una aplicación con píxeles independientes solo si todos los dispositivos en los que se ejecuta la aplicación comparten la misma densidad de píxeles (ppi) en sus pantallas. Sin embargo, en realidad, cada fabricante crea sus propias pantallas de densidad de píxeles.

Vamos a crear un mecanismo para una interfaz de usuario receptiva

La idea es simple. Dado que el porcentaje no siempre funcionará, proporcionemos el valor dp "correcto" para cada pantalla de forma dinámica. Veamos un ejemplo de cómo hacerlo. A continuación podemos ver la escena del perfil del juego para Android Math Warriors. Centrémonos en las 4 grandes baldosas azules en la mitad inferior:

Imagen 2: Escena de perfil del juego para Android Math Warriors

Lo que queremos lograr aquí para que nuestro diseño sea receptivo es que los mosaicos ocupen más del 98% del ancho de la pantalla en dp y el 10% de la altura de la pantalla en dp. Y ese debería ser el caso para cada pantalla. Eso se traduce en:

Identifiquemos las dimensiones de la pantalla (ancho, alto) en dp y luego multiplíquelo por un factor, en nuestro caso 98% y 10% para ancho y alto respectivamente. Para mayor flexibilidad en nuestro código, creamos las 2 funciones a continuación:

importar {Dimensiones, PixelRatio} desde 'react-native';
const widthPercentageToDP = widthPercent => {
  const screenWidth = Dimensions.get ('ventana'). ancho;
  // Convertir entrada de cadena a número decimal
  const elemWidth = parseFloat (widthPercent);
  return PixelRatio.roundToNearestPixel (screenWidth * elemWidth / 100);
};
const heightPercentageToDP = heightPercent => {
  const screenHeight = Dimensions.get ('ventana'). height;
  // Convertir entrada de cadena a número decimal
  const elemHeight = parseFloat (heightPercent);
return PixelRatio.roundToNearestPixel (screenHeight * elemHeight / 100);
};
exportar {
  widthPercentageToDP,
  heightPercentageToDP
};

Y ahora dentro de nuestra vista de Perfil, simplemente llamamos a las funciones al proporcionar la cantidad de porcentaje deseada (para ancho o alto) como argumento. Para el ejemplo anterior, tenemos el siguiente código (de nuevo, la sintaxis incómoda se debe al uso de componentes con estilo):

const Tile = styled.View`
  ancho: $ {widthPercentageToDP ('98% ')};
  height: $ {heightPercentageToDP ('10% ')};
    .
    .
    .
`;

¡De esa forma podemos generar un resultado dinámico que se adapte a todos los tamaños de pantalla diferentes!

¡Probemos nuestro ejemplo!

Para verificar nuestro desarrollo de UI, tenemos un conjunto de emuladores de Android e iOS que utilizamos para verificar los resultados. Veamos cómo se ha transformado nuestro código a la interfaz de usuario:

Teléfonos inteligentes

Imágenes 3, 4, 5: Vista de perfil en dispositivos de teléfonos inteligentes con diferente densidad de píxeles, factor de escala, etc.

Tabletas

Imagen 6: Vista de perfil en tabletas con diferente densidad de píxeles, factor de escala, etc.

¿Qué piensas?

¿Qué opinas de esta solución? Siéntase libre de ofrecer su perspectiva e ideas a la sección de comentarios a continuación.

EDITAR: El código explicado aquí está disponible como una solución completa a través de un paquete gratuito de código abierto llamado react-native-responsive-screen. ¡Compruébalo y descubre lo fácil que es usarlo! Feliz codificación :-)

Si disfrutaste este artículo, siéntete libre de presionar el botón de aplaudir para ayudar a otros a encontrarlo.

Sobre mi

Hola, soy Tasos; un ingeniero de software que ama la web y actualmente trabaja mucho con React Native y React. Soy cofundador de la agencia de software Coded Lines, donde realizamos proyectos móviles y web de extremo a extremo con énfasis en el marketing en la aplicación. Si suena lo que está buscando, contácteme aquí: tasos.maroudas@codedlines.com. Gracias por pasar :)