Comment développer des UI réactives avec React Native - 1x03

Cette histoire fait partie d’une série dans laquelle je partage mes expériences sur React Native: comment j’ai abordé et travaillé avec des composants RN, des API, des packages externes et toutes sortes de problèmes. J'espère que cette série de messages sera utile à la communauté autochtone de React et fournira des informations utiles.

EDIT: Le code expliqué ici est disponible sous forme de solution complète via un package gratuit et à code source ouvert appelé react-native-responsive-screen. Jetez-y un œil et découvrez à quel point il est simple à utiliser! Bonne codage :-)

Qu'en est-il de l'interface utilisateur réactive?

L'interface utilisateur réactive est importante! Aucun développeur d’interface utilisateur ne peut le nier, alors que la plupart d’entre nous ont eu du mal à en livrer un. En tant que développeur natif de React, vous devez fournir le même résultat ou des résultats très similaires pour de nombreux écrans de mobile et de tablette de différentes tailles, analyse, facteur d’échelle, densité de pixels, etc.

Image 1: A quoi ressemble une interface utilisateur réactive dans plusieurs périphériques

Quand j'ai commencé à coder avec RN, je me souviens avoir pensé:

Il doit exister un mécanisme interne du cadre pour traiter la réactivité - sinon, dans le pire des cas, j'utiliserai les pourcentages partout…

Ces deux hypothèses étaient pourtant erronées… Et je l'ai découverte à la dure lorsque j'ai commencé à développer ma première interface utilisateur.

Le pourcentage de valeur CSS n'est PAS entièrement pris en charge

Bien que cela se soit beaucoup amélioré depuis 1 an et plus, c'est toujours le cas. Certaines propriétés CSS ne prennent pas en charge les valeurs de pourcentage dans RN, mais elles le font dans le développement Web «normal». Pour n'en citer que quelques-uns: marge, largeur-bordure et rayon-bordure. Et si quelqu'un essaie de définir une valeur en pourcentage, RN l'ignorera complètement ou l'application se bloquera.

Des améliorations sont apportées et un support est ajouté au fil du temps. Attendre que la structure se rattrape est cependant prohibitif pour les personnes qui travaillent déjà avec React Native dans des applications de production. Restez avec moi pour examiner de plus près quelques mécanismes RN, comment notre équipe a trouvé une solution et un exemple réel de notre travail.

Réagir aux pixels natifs et indépendants

Lorsque vous codez une valeur CSS en «pixels» dans React Native, il s’agit en fait de pixels indépendants (dp ou dpi) et non de pixels à l’écran. Il s’agit d’une unité de mesure différente (probablement inspirée de son utilisation dans le développement d’Android) que RN utilise en interne.

Jetons un coup d’œil au code suivant (nous utilisons le package et la syntaxe des composants stylés au lieu d’accéder directement au composant RN StyleSheet):

const HeaderText = styled.Text`
  rembourrage en haut: 20;
  taille de police: 15;
  famille de polices: Kano;
  largeur: 100%;
  text-align: center;
`;

Vous pouvez voir que les propriétés padding-top et font-size sont écrites sous forme de nombres simples et qu'il n'y a pas de suffixe px à côté d'elles. Pour trouver les pixels réels de l'écran, nous pouvons utiliser l'équation suivante:

px = dp * scaleFactor

Pour plus d’informations, vous pouvez consulter le guide Android relatif aux densités de pixels, la présentation de la compatibilité d’écrans d’Android et le guide Paintcodeapp pour les résolutions iPhone.

Quelqu'un pourrait penser ici que nous pouvons utiliser des pixels indépendants partout et obtenir l'interface utilisateur réactive que nous recherchons. Malheureusement, ce n'est pas le cas car scaleFactor dépend de la densité de pixels. Cela dit, nous ne pourrions développer une application avec des pixels indépendants que si tous les appareils sur lesquels elle s'exécutait partagent la même densité de pixels (ppp) sur leurs écrans. En réalité, chaque fabricant crée ses propres écrans de densité de pixels.

Imaginons un mécanisme d’interface utilisateur réactive

L'idée est simple. Étant donné que le pourcentage ne fonctionne pas toujours, fournissons de manière dynamique la valeur «correcte» de dp pour chaque écran différent. Voyons un exemple de la façon de le faire. Ci-dessous, nous pouvons voir la scène de profil du jeu Math Warriors pour Android. Concentrons-nous sur les 4 gros carreaux bleus de la moitié inférieure:

Image 2: Scène de profil de Math Warriors sur Android

Ce que nous voulons réaliser ici pour que notre conception soit réactive, c’est que les carreaux représentent 98% de la largeur de l’écran en dp et 10% de sa hauteur en dp. Et cela devrait être le cas pour chaque écran. Cela se traduit par:

Identifions les dimensions de l’écran (largeur, hauteur) en dp puis multiplions-le par un facteur - dans notre cas 98% et 10% respectivement pour la largeur et la hauteur. Pour plus de flexibilité dans notre code, nous créons les 2 fonctions ci-dessous:

importer {Dimensions, PixelRatio} de 'react-native';
const widthPercentageToDP = widthPercent => {
  const screenWidth = Dimensions.get ('window'). width;
  // Convertit une entrée de chaîne en nombre décimal
  const elemWidth = parseFloat (widthPercent);
  return PixelRatio.roundToNearestPixel (screenWidth * elemWidth / 100);
};
const heightPercentageToDP = heightPercent => {
  const screenHeight = Dimensions.get ('fenêtre'). hauteur;
  // Convertit une entrée de chaîne en nombre décimal
  const elemHeight = parseFloat (heightPercent);
renvoyez PixelRatio.roundToNearestPixel (screenHeight * elemHeight / 100);
};
exportation {
  widthPercentageToDP,
  heightPercentageToDP
};

Et maintenant, dans notre vue Profil, nous appelons simplement les fonctions en fournissant comme argument le pourcentage souhaité (pour la largeur ou la hauteur). Pour l'exemple ci-dessus, nous avons le code suivant (encore une fois, la syntaxe maladroite est due à l'utilisation de composants stylés):

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

De cette façon, nous pouvons générer un résultat dynamique qui s'adapte à toutes les tailles d'écran!

Testons notre exemple!

Afin de vérifier le développement de notre interface utilisateur, nous disposons d’un ensemble d’émulateurs Android, iOS, que nous utilisons pour vérifier les résultats. Voyons comment notre code a été transformé en interface utilisateur:

Smartphones

Images 3, 4, 5: Vue du profil sur les smartphones avec une densité de pixels, un facteur d'échelle, etc. différents

Comprimés

Image 6: Vue de profil dans les tablettes avec une densité de pixels, un facteur d'échelle, etc. différents

Qu'est-ce que tu penses?

Que pensez-vous de cette solution? N'hésitez pas à offrir votre point de vue et vos idées à la section commentaires ci-dessous.

EDIT: Le code expliqué ici est disponible sous forme de solution complète via un package gratuit et à code source ouvert appelé react-native-responsive-screen. Jetez-y un œil et découvrez à quel point il est simple à utiliser! Bonne codage :-)

Si vous avez aimé cet article, n'hésitez pas à appuyer sur ce bouton pour aider les autres à le trouver.

À propos de moi

Bonjour, je suis Tasos. Un ingénieur logiciel qui aime le Web et qui travaille beaucoup avec React Native et React. Je suis le cofondateur de l'agence de logiciels Coded Lines, où nous réalisons des projets Web et mobiles de bout en bout en mettant l'accent sur le marketing intégré à l'application. Si cela vous convient, contactez-moi ici: tasos.maroudas@codedlines.com. Merci d'être passé :)