Comment faire en sorte que votre application React Native réponde gracieusement lorsque le clavier apparaît

Lorsque vous travaillez avec des applications React Native, un problème courant est que le clavier apparaîtra et masquera les entrées de texte lorsque vous vous concentrez sur elles. Quelque chose comme ça:

Vous pouvez éviter cela de plusieurs manières. Certains sont simples, d'autres moins. Certains peuvent être personnalisés, d'autres non. Aujourd'hui, je vais vous montrer 3 façons différentes d'éviter le clavier dans React Native.

J'ai mis tout le code source de ce tutoriel sur Github.

KeyboardAvoidingView

La solution la plus simple et la plus simple à installer est KeyboardAvoidingView. C'est un composant de base mais c'est aussi assez simple dans ce qu'il fait.

Vous pouvez prendre le code de base, qui a le clavier couvrant les entrées, et le mettre à jour afin que les entrées ne soient plus couvertes. La première chose à faire est de remplacer le conteneur Viewpar le KeyboardAvoidingView, puis d'y ajouter un behavioraccessoire. Si vous regardez la documentation, vous verrez qu'elle accepte 3 valeurs différentes - hauteur, remplissage, position . J'ai trouvé que le rembourrage fonctionne de la manière la plus prévisible. C'est donc ce que je vais utiliser.

import React from 'react'; import { View, TextInput, Image, KeyboardAvoidingView } from 'react-native'; import styles from './styles'; import logo from './logo.png'; const Demo = () => { return (         ); }; export default Demo;

Cela nous donne le résultat suivant. Ce n'est pas parfait mais pour presque aucun travail, c'est assez bon.

Une chose à noter est que sur la ligne 30, vous verrez un Viewqui a une hauteur réglée à 60px. J'ai trouvé que le clavier évitant la vue ne fonctionnait pas tout à fait avec le dernier élément et que le réglage du rembourrage / de la marge ne fonctionnait pas. J'ai donc ajouté un nouvel élément pour tout «bump» de quelques pixels.

L'image en haut est poussée hors de la vue lors de l'utilisation de cette implémentation simple. Je vais vous montrer comment vous pouvez résoudre ce problème à la fin.

Utilisateurs d'Android: j'ai trouvé que c'était la meilleure / la seule option. En ajoutant android:windowSoftInputMode="adjustResize"à votre AndroidManifest.xml, le système d'exploitation se chargera de la plupart du travail pour vous et KeyboardAvoidingView se chargera du reste. Exemple AndroidManifest.xml. Le reste de cet article ne s'appliquera probablement pas à vous.

ScrollView sensible au clavier

L'option suivante est la vue de défilement sensible au clavier, qui vous en donne beaucoup pour votre argent. Dans les coulisses, il utilise un ScrollView ou une ListView pour tout gérer (selon le composant que vous choisissez), ce qui rend l'interaction de défilement assez transparente. L'autre avantage majeur de ce package est qu'il défilera jusqu'à l'entrée qui est au point, ce qui donne à l'utilisateur une expérience agréable.

L'utilisation est également très simple - il vous suffit de remplacer le conteneur View, en commençant à nouveau par le code de base et de définir quelques options. Voici le code, puis je le décrirai.

import React from 'react'; import { View, TextInput, Image } from 'react-native'; import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view' import styles from './styles'; import logo from './logo.png'; const Demo = () => { return (        ); }; export default Demo;

Tout d'abord, vous voulez définir le backgroundColor du ScrollView de cette façon (si vous deviez réactiver le défilement), le backgroundColor est toujours le même. Ensuite, vous voulez indiquer au composant où se trouve la position par défaut de sorte qu'une fois le clavier fermé, il retourne à cet endroit - en omettant cet accessoire, la vue pourrait rester bloquée en haut après la fermeture du clavier, comme ceci.

Après la prop resetScrollToCoords, vous définissez le contentContainerStyle - cela remplace essentiellement les Viewstyles contenant que vous aviez auparavant. La dernière chose que je fais est de désactiver la vue de défilement de l'interaction de l'utilisateur. Cela n'a pas toujours de sens pour votre interface utilisateur (comme une interface où un utilisateur modifie de nombreux champs de profil) mais pour celui-ci, cela n'a pas beaucoup de sens de permettre à l'utilisateur de faire défiler manuellement car il n'y a rien à faire défiler à.

En combinant ces accessoires, vous obtenez le résultat suivant, qui fonctionne très bien.

Module clavier

C'est de loin l'option la plus manuelle, mais elle vous donne également le plus de contrôle. Vous utiliserez la bibliothèque animée pour vous aider à créer des interactions fluides comme vous l'avez vu auparavant.

Le module Clavier, qui n'est pas documenté sur le site React Native, vous permet d'écouter les événements clavier émis par l'appareil. Les événements que vous utiliserez sont keyboardWillShow et keyboardWillHide , qui renvoient la durée de l'animation et la position de fin du clavier (entre autres informations).

Si vous êtes sur Android, vous voudrez plutôt utiliser keyboardDidShow et keyboardDidHide.

Lorsque l' événement keyboardWillShow est émis, vous définissez une variable animée à la hauteur finale du clavier et l'animez pendant la même durée que l'animation de glissement du clavier. Vous utilisez ensuite cette valeur animée pour définir un remplissage au bas du conteneur afin de remonter tout le contenu.

Je vais montrer le code dans un instant, mais faire ce que j'ai décrit ci-dessus nous laisse avec cette expérience.

Je veux corriger cette image cette fois. Pour ce faire, vous utiliserez une valeur animée pour gérer la hauteur de l'image, que vous ajusterez à l'ouverture du clavier. Voici le code.

import React, { Component } from 'react'; import { View, TextInput, Image, Animated, Keyboard } from 'react-native'; import styles, { IMAGE_HEIGHT, IMAGE_HEIGHT_SMALL} from './styles'; import logo from './logo.png'; class Demo extends Component { constructor(props) { super(props); this.keyboardHeight = new Animated.Value(0); this.imageHeight = new Animated.Value(IMAGE_HEIGHT); } componentWillMount () { this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide); } componentWillUnmount() { this.keyboardWillShowSub.remove(); this.keyboardWillHideSub.remove(); } keyboardWillShow = (event) => { Animated.parallel([ Animated.timing(this.keyboardHeight, { duration: event.duration, toValue: event.endCoordinates.height, }), Animated.timing(this.imageHeight, { duration: event.duration, toValue: IMAGE_HEIGHT_SMALL, }), ]).start(); }; keyboardWillHide = (event) => { Animated.parallel([ Animated.timing(this.keyboardHeight, { duration: event.duration, toValue: 0, }), Animated.timing(this.imageHeight, { duration: event.duration, toValue: IMAGE_HEIGHT, }), ]).start(); }; render() { return (        ); } }; export default Demo;

Il y a certainement beaucoup plus que n'importe quelle autre solution. Plutôt qu'une normale Viewou Imagevous utilisez un Animated.Viewet Animated.Imagepour que les valeurs animées puissent être exploitées. La partie amusante est vraiment dans les fonctions keyboardWillShow et keyboardWillHide où les valeurs animées changent.

Ce qui se passe là-bas, c'est que deux valeurs animées changent en parallèle qui sont ensuite utilisées pour piloter l'interface utilisateur. Cela vous laisse avec ça.

C'est beaucoup plus de code mais c'est assez astucieux. Vous avez beaucoup d'options pour ce que vous pouvez faire et pouvez vraiment personnaliser l'interaction à votre guise.

Combinaison d'options

Si vous souhaitez enregistrer du code, vous pouvez combiner quelques options, ce que j'ai tendance à faire. Par exemple, en combinant les options 1 et 3, vous n'avez qu'à vous soucier de la gestion et de l'animation de la hauteur de l'image.

Le code n'est pas beaucoup moins que la source de l'option 3, mais à mesure qu'une interface utilisateur devient de plus en plus complexe, elle peut vous aider un peu.

import React, { Component } from 'react'; import { View, TextInput, Image, Animated, Keyboard, KeyboardAvoidingView } from 'react-native'; import styles, { IMAGE_HEIGHT, IMAGE_HEIGHT_SMALL } from './styles'; import logo from './logo.png'; class Demo extends Component { constructor(props) { super(props); this.imageHeight = new Animated.Value(IMAGE_HEIGHT); } componentWillMount () { this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow); this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide); } componentWillUnmount() { this.keyboardWillShowSub.remove(); this.keyboardWillHideSub.remove(); } keyboardWillShow = (event) => { Animated.timing(this.imageHeight, { duration: event.duration, toValue: IMAGE_HEIGHT_SMALL, }).start(); }; keyboardWillHide = (event) => { Animated.timing(this.imageHeight, { duration: event.duration, toValue: IMAGE_HEIGHT, }).start(); }; render() { return (        ); } }; export default Demo;

Chaque implémentation a ses avantages et ses inconvénients: vous devrez choisir la plus appropriée compte tenu de l'expérience utilisateur que vous visez.

Souhaitez-vous en savoir plus sur l'utilisation de React Native pour créer des applications mobiles de haute qualité? Inscrivez-vous à mon cours gratuit React Native!