Cómo hacer que su aplicación React Native responda con elegancia cuando aparece el teclado

Cuando trabaja con aplicaciones React Native, un problema común es que el teclado se abrirá y ocultará las entradas de texto cuando se concentre en ellas. Algo como esto:

Hay algunas formas de evitarlo. Algunos son simples, otros menos. Algunos se pueden personalizar, otros no. Hoy te mostraré 3 formas diferentes en las que puedes evitar el teclado en React Native.

He puesto todo el código fuente de este tutorial en Github.

KeyboardEvoidingView

La solución más simple y más fácil de instalar es KeyboardAvoidingView. Es un componente central, pero también es bastante simple en lo que hace.

Puede tomar el código base, que tiene el teclado cubriendo las entradas, y actualizarlo para que las entradas ya no estén cubiertas. Lo primero que tienes que hacer es reemplazar el contenedor Viewcon el KeyboardAvoidingViewy luego agregarle un behavioraccesorio. Si observa la documentación, verá que acepta 3 valores diferentes: altura, relleno y posición . Descubrí que el acolchado funciona de la manera más predecible. Entonces eso es lo que usaré.

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;

Esto nos da el siguiente resultado. No es perfecto, pero para casi cualquier trabajo es bastante bueno.

Una cosa a tener en cuenta es que en la línea 30 verá una Viewque tiene una altura establecida en 60px. Descubrí que el teclado que evita la vista no funciona del todo con el último elemento, y la configuración de relleno / margen no funcionó. Así que agregué un nuevo elemento para "aumentar" todo unos pocos píxeles.

La imagen de la parte superior desaparece de la vista cuando se utiliza esta sencilla implementación. Te mostraré cómo puedes solucionarlo al final.

Usuarios de Android: He encontrado que esta es la mejor / única opción. Al agregar android:windowSoftInputMode="adjustResize"a su AndroidManifest.xml, el sistema operativo se encargará de la mayor parte del trabajo por usted y KeyboardAvoidingView se encargará del resto. Ejemplo AndroidManifest.xml. Es probable que el resto de este artículo no se aplique a usted.

ScrollView con reconocimiento de teclado

La siguiente opción es react-native-keyboard-awareness-scroll-view que le da mucho por su dinero. Detrás de escena, usa ScrollView o ListView para manejar todo (dependiendo del componente que elija), lo que hace que la interacción de desplazamiento sea bastante fluida. El otro beneficio importante de este paquete es que se desplazará a la entrada que está enfocada, lo que le brinda al usuario una experiencia agradable.

El uso también es muy fácil: solo necesita cambiar el contenedor View, nuevamente comenzando con el código base y establecer algunas opciones. Aquí está el código, luego lo describiré.

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;

En primer lugar, desea establecer el backgroundColor de ScrollView de esa manera (si tuviera que volver a habilitar el desplazamiento), backgroundColor es siempre el mismo. A continuación, desea decirle al componente dónde está la posición predeterminada para que, una vez que el teclado esté cerrado, vuelva a ese lugar; al omitir este accesorio, la vista podría atascarse en la parte superior después de cerrar el teclado, de esta manera.

Después del accesorio resetScrollToCoords , estableces contentContainerStyle; esto esencialmente reemplaza los Viewestilos de contención que tenías antes. Lo último que estoy haciendo es deshabilitar la vista de desplazamiento de la interacción del usuario. Es posible que esto no siempre tenga sentido para su interfaz de usuario (como una interfaz en la que un usuario está editando muchos campos de perfil), pero en este caso, no tiene mucho sentido permitir que el usuario se desplace manualmente porque no hay nada para desplazarse. a.

Al combinar estos accesorios, se obtiene el siguiente resultado, que funciona bastante bien.

Módulo de teclado

Esta es, con mucho, la opción más manual, pero también le brinda el mayor control. Utilizará la biblioteca animada para ayudar a brindar interacciones fluidas como las que vio antes.

El módulo de teclado, que no está documentado en el sitio React Native, le permite escuchar los eventos de teclado emitidos desde el dispositivo. Los eventos que utilizará son keyboardWillShow y keyboardWillHide , que devuelven el tiempo que tardará la animación y la posición final del teclado (entre otra información).

Si está en Android, querrá usar keyboardDidShow y keyboardDidHide en su lugar.

Cuando se emite el evento keyboardWillShow , establecerá una variable animada a la altura final del teclado y la animará durante la misma duración que la animación deslizante del teclado. Luego, usa este valor animado para configurar el relleno en la parte inferior del contenedor para aumentar todo el contenido.

Mostraré el código en un momento, pero hacer lo que describí anteriormente nos deja con esta experiencia.

Quiero arreglar esa imagen esta vez. Para hacerlo, usará un valor animado para administrar la altura de la imagen, que ajustará cuando se abra el teclado. Aquí está el código.

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;

Ciertamente, hay mucho más que cualquier otra solución. En lugar de uno normal Viewo Imageestá usando un Animated.Viewy Animated.Imagepara que los valores animados se puedan aprovechar. La parte divertida está realmente en las funciones keyboardWillShow y keyboardWillHide donde los valores animados están cambiando.

Lo que sucede allí es que dos valores animados están cambiando en paralelo que luego se utilizan para impulsar la interfaz de usuario. Eso te deja con esto.

Es bastante más código, pero es bastante hábil. Tiene muchas opciones para lo que puede hacer y realmente puede personalizar la interacción al contenido de su corazón.

Combinando Opciones

Si desea guardar algún código, puede combinar algunas opciones, que es lo que suelo hacer. Por ejemplo, al combinar la opción 1 y 3 solo tienes que preocuparte de administrar y animar la altura de la imagen.

El código no es mucho menor que la fuente de la opción 3, pero a medida que una interfaz de usuario aumenta en complejidad, puede ayudarlo un poco.

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;

Cada implementación tiene sus pros y sus contras: tendrás que elegir la más adecuada según la experiencia de usuario que buscas.

¿Está interesado en aprender más sobre el uso de React Native para crear aplicaciones móviles de alta calidad? ¡Regístrese en mi curso React Native gratuito!