Як змусити додаток React Native витончено реагувати, коли з’являється клавіатура

Коли ви працюєте з програмами React Native, найпоширенішою проблемою є те, що клавіатура спливає і приховує введення тексту, коли ви фокусуєтеся на них. Щось на зразок цього:

Є кілька способів уникнути цього. Хтось простий, хтось менш. Деякі можна налаштувати, інші - ні. Сьогодні я покажу вам 3 різні способи, як уникнути клавіатури в React Native.

Весь вихідний код цього підручника я розмістив на Github.

KeyboardAvoidingView

Найпростішим рішенням і найпростішим у встановленні є KeyboardAvoidingView. Це основний компонент, але він також досить простий у тому, що він робить.

Ви можете взяти базовий код, який має клавіатуру, що покриває входи, і оновити його так, щоб входи більше не були покриті. Перше, що вам потрібно зробити, це замінити контейнер Viewна, KeyboardAvoidingViewа потім додати behaviorдо нього реквізит. Якщо ви подивитесь на документацію, то побачите, що вона приймає 3 різні значення - висоту, відступ, положення . Я виявив, що прокладки працюють найбільш передбачувано. Отже, це те, що я буду використовувати.

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;

Це дає нам такий результат. Це не ідеально, але для майже будь-якої роботи, це цілком непогано.

Зазначимо одне, що на рядку 30 ви побачите Viewвисоту, встановлену на 60 пікселів. Я виявив, що клавіатура, яка уникає подання, не зовсім працює з останнім елементом, і встановлення відступів / полів не спрацювало. Тож я додав новий елемент, щоб «підняти» все на кілька пікселів.

Зображення у верхній частині виштовхується з поля зору при використанні цієї простої реалізації. Я покажу вам, як ви можете це виправити наприкінці.

Користувачі Android: Я вважаю, що це найкращий / єдиний варіант. Додавши android:windowSoftInputMode="adjustResize"до свого AndroidManifest.xml, операційна система подбає про більшість робіт за вас, а KeyboardAvoidingView - про все інше. Приклад AndroidManifest.xml. Решта цієї статті, ймовірно, не стосуватиметься вас.

Клавіатура з урахуванням ScrollView

Наступним варіантом є реакція-рідна-клавіатура-відома-перегляд прокрутки, яка дає вам багато удару за ваші гроші. За лаштунками він використовує ScrollView або ListView, щоб обробляти все (залежно від вибраного компонента), що робить взаємодію прокрутки досить безшовною. Інша основна перевага цього пакету полягає в тому, що він перейде до вхідного сигналу, який знаходиться у фокусі, що надає користувачеві приємний досвід.

Використання також дуже просте - вам просто потрібно поміняти контейнер View, знову починаючи з базового коду, і встановити кілька параметрів. Ось код, тоді я його опишу.

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;

По-перше, ви хочете встановити backgroundColor у ScrollView таким чином (якщо ви хочете ввімкнути прокрутку), backgroundColor завжди однаковий. Далі ви хочете повідомити компоненту, де знаходиться положення за замовчуванням, щоб, як тільки клавіатура закрита, вона повернулася до цього місця - пропустивши цей опис, вигляд міг застрягти вгорі після закриття клавіатури, наприклад.

Після підстановки resetScrollToCoords ви встановлюєте contentContainerStyle - це по суті замінює містять Viewстилі, які ви мали раніше. Нарешті, що я роблю, це вимкнення режиму прокрутки від взаємодії з користувачем. Це може не завжди мати сенс для вашого інтерфейсу користувача (наприклад, інтерфейсу, де користувач редагує безліч полів профілю), але для цього він не має сенсу дозволяти користувачеві прокручувати вручну, оскільки прокручувати нічого до.

Поєднуючи ці реквізити, ви отримуєте такий результат, який працює досить добре.

Модуль клавіатури

Це, безумовно, найбільш ручний варіант, але також дає вам найбільший контроль. Ви будете використовувати анімаційну бібліотеку, щоб допомогти забезпечити плавні взаємодії, як ви бачили раніше.

Модуль клавіатури, який не задокументований на сайті React Native, дозволяє прослуховувати події клавіатури, що випускаються з пристрою. Події, якими ви будете користуватися, - це keyboardWillShow та keyboardWillHide , які повертають тривалість анімації та кінцеве положення клавіатури (серед іншої інформації).

Якщо ви користуєтеся Android, замість цього ви захочете використовувати keyboardDidShow та keyboardDidHide.

Коли емітується подія keyboardWillShow , ви встановите анімовану змінну до кінцевої висоти клавіатури та забезпечите її анімацію на той самий час, що і анімація ковзання клавіатури. Потім ви використовуєте це анімоване значення, щоб встановити відступ внизу контейнера, щоб підняти весь вміст.

Я покажу код за мить, але виконання описаного вище залишає нам такий досвід.

Цього разу я хочу виправити це зображення. Для цього ви використовуєте анімоване значення для управління висотою зображення, яке ви регулюєте, коли клавіатуру відкрито. Ось код.

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;

У цьому, безумовно, набагато більше, ніж у будь-якому іншому рішенні. Замість звичайного Viewабо Imageви використовуєте Animated.Viewа, Animated.Imageщоб анімовані значення можна було використовувати. Найцікавіша частина справді полягає у функціях keyboardWillShow та keyboardWillHide, де анімовані значення змінюються.

Що відбувається там, так це те, що паралельно змінюються два анімовані значення, які потім використовуються для керування інтерфейсом. Це залишає вас із цим.

Це набагато більше коду, але він досить витончений. У вас є безліч варіантів того, що ви можете зробити, і ви дійсно можете налаштувати взаємодію на свій смак.

Поєднання варіантів

Якщо ви хочете зберегти деякий код, ви можете поєднати кілька варіантів, що я, як правило, роблю. Наприклад, поєднуючи варіанти 1 та 3, вам доведеться лише турбуватися про управління та анімацію висоти зображення.

Код не набагато менше джерела варіанту 3, але в міру ускладнення користувальницького інтерфейсу він може вам трохи допомогти.

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;

Кожне впровадження має свої плюси і мінуси - вам доведеться вибрати найбільш підходящий з урахуванням досвіду користувача, на який ви прагнете.

Ви хочете дізнатись більше про використання React Native для створення високоякісних мобільних додатків? Підпишіться на мій безкоштовний курс React Native!