キーボードがポップアップしたときにReactNativeアプリが適切に応答するようにする方法

React Nativeアプリを使用している場合、一般的な問題は、キーボードにフォーカスすると、キーボードがポップアップしてテキスト入力が非表示になることです。このようなもの:

これを回避する方法はいくつかあります。単純なものもあれば、それほど単純でないものもあります。カスタマイズできるものもあれば、できないものもあります。今日は、ReactNativeでキーボードを回避する3つの方法を紹介します。

このチュートリアルのすべてのソースコードをGithubに配置しました。

KeyboardAvoidingView

最も単純なソリューションであり、インストールが最も簡単なのは、KeyboardAvoidingViewです。これはコアコンポーネントですが、機能も非常にシンプルです。

キーボードが入力をカバーしているベースコードを取得し、それを更新して入力がカバーされなくなるようにすることができます。最初に行う必要があるのは、コンテナViewをに置き換えてKeyboardAvoidingViewから、それにbehavior小道具を追加することです。ドキュメントを見ると、height、padding、positionの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;

これにより、次の結果が得られます。それは完璧ではありませんが、ほとんどどんな仕事にも、それはかなり良いです。

注意すべき点の1つは、30行目にView高さが60pxに設定されているが表示されることです。キーボード回避ビューが最後の要素では完全に機能せず、パディング/マージンの設定が機能しないことがわかりました。そこで、新しい要素を追加して、すべてを数ピクセル上に「バンプ」しました。

この単純な実装を使用すると、上部の画像がビューから押し出されます。最後にそれを修正する方法を紹介します。

Androidユーザー:これが最良の/唯一のオプションであることがわかりました。android:windowSoftInputMode="adjustResize"AndroidManifest.xmlに追加することで、オペレーティングシステムがほとんどの作業を処理し、KeyboardAvoidingViewが残りの作業を処理します。AndroidManifest.xmlの例。この記事の残りの部分は、おそらくあなたには当てはまりません。

キーボード対応ScrollView

次のオプションはreact-native-keyboard-aware-scroll-viewで、これはあなたに大金を稼ぎます。舞台裏では、ScrollViewまたはListViewを使用してすべてを処理し(選択したコンポーネントに応じて)、スクロールの相互作用を非常にシームレスにします。このパッケージのもう1つの大きな利点は、フォーカスされている入力にスクロールすることです。これにより、ユーザーは優れたエクスペリエンスを得ることができます。

使用法も非常に簡単です。コンテナを交換し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あなたが前に持っていたスタイルを。私がしている最後のことは、ユーザー操作からスクロールビューを無効にすることです。これは、UI(ユーザーが多くのプロファイルフィールドを編集しているインターフェイスなど)にとって常に意味があるとは限りませんが、この場合は、スクロールするものがないため、ユーザーが手動でスクロールできるようにすることはあまり意味がありません。に。

これらの小道具を組み合わせると、次の結果が得られます。これは非常にうまく機能します。

キーボードモジュール

これは圧倒的に最も手動のオプションですが、最も制御しやすくなります。アニメーションライブラリを使用して、前に見たようなスムーズなインタラクションを提供します。

React Nativeサイトに記載されていないKeyboardモジュールを使用すると、デバイスから発行されたキーボードイベントをリッスンできます。使用するイベントはkeyboardWillShowkeyboardWillHideで、アニメーションにかかる時間の長さとキーボードの終了位置(その他の情報)を返します。

Androidを使用している場合は、代わりにkeyboardDidShowとkeyboardDidHideを使用することをお勧めします。

ときkeyboardWillShowのイベントが放出されますが、キーボードの最終高さにアニメーション変数を設定し、それはキーボードのスライドアニメーションと同じ期間のアニメーションがあります。次に、このアニメーション値を使用して、コンテナの下部にパディングを設定し、すべてのコンテンツをバンプします。

I’ll show code in a moment, but doing what I described above leaves us with this experience.

I want to fix that image this time. To do so you’ll use an animated value to manage the height of the image, which you’ll adjust when the keyboard is opened. Here’s the 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;

There’s certainly a lot more to it than any of the other solutions. Rather than a normal View or Image you’re using an Animated.View and Animated.Image so that the animated values can be leveraged. The fun part is really in the keyboardWillShow and keyboardWillHide functions where the animated values are changing.

What’s happening there is that two animated values are changing in parallel which are then being used to drive the UI. That leaves you with this.

それはかなり多くのコードですが、かなり洗練されています。あなたはあなたができることについて多くのオプションがあり、あなたの心のコンテンツへの相互作用を本当にカスタマイズすることができます。

オプションの組み合わせ

いくつかのコードを保存したい場合は、いくつかのオプションを組み合わせることができます。これは私がよく行うことです。たとえば、オプション1と3を組み合わせると、画像の高さの管理とアニメーション化についてのみ心配する必要があります。

コードはオプション3のソースよりもはるかに少なくはありませんが、UIが複雑になるにつれて、少し役立つことがあります。

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を使用して高品質のモバイルアプリを構築する方法について詳しく知りたいですか?無料のReactNativeコースにサインアップしてください!