Cara membuat aplikasi React Native anda bertindak balas dengan anggun ketika papan kekunci muncul

Semasa anda bekerja dengan aplikasi React Native, masalah umum ialah papan kekunci akan muncul dan menyembunyikan input teks apabila anda memfokuskannya. Sesuatu seperti ini:

Terdapat beberapa cara untuk mengelakkannya. Ada yang sederhana, ada yang kurang. Beberapa boleh disesuaikan, yang lain tidak dapat. Hari ini saya akan menunjukkan 3 cara berbeza untuk mengelakkan papan kekunci di React Native.

Saya telah meletakkan semua kod sumber untuk tutorial ini di Github.

Papan KekunciMengelakkan Pandangan

Penyelesaian yang paling mudah, dan yang paling mudah dipasang, adalah KeyboardAvoidingView. Ini adalah komponen inti tetapi ia juga cukup mudah dalam pelaksanaannya.

Anda boleh mengambil kod asas, yang mempunyai papan kekunci yang meliputi input, dan memperbaharui sehingga input tidak lagi ditutup. Perkara pertama yang harus anda lakukan ialah ganti bekas Viewdengan KeyboardAvoidingViewdan kemudian tambahkan alat behaviorpenyangga ke dalamnya. Sekiranya anda melihat dokumentasi anda akan melihat bahawa ia menerima 3 nilai yang berbeza - tinggi, pelapik, kedudukan . Saya dapati padding berfungsi dengan cara yang paling boleh diramalkan. Jadi itulah yang akan saya gunakan.

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;

Ini memberikan hasil berikut. Ia tidak sempurna tetapi hampir tidak ada kerja, cukup bagus.

Satu perkara yang perlu diperhatikan ialah pada baris 30 anda akan melihat Viewketinggian yang ditetapkan hingga 60 piksel. Saya dapati paparan mengelakkan papan kekunci tidak berfungsi dengan elemen terakhir, dan menetapkan padding / margin tidak berfungsi. Oleh itu, saya menambah elemen baru untuk "menaikkan" segalanya sehingga beberapa piksel.

Gambar di bahagian atas ditolak dari pandangan ketika menggunakan pelaksanaan sederhana ini. Saya akan menunjukkan kepada anda bagaimana anda boleh memperbaikinya pada akhirnya.

Pengguna Android: Saya menganggap ini sebagai pilihan terbaik / satu-satunya. Dengan menambahkan android:windowSoftInputMode="adjustResize"ke AndroidManifest.xml sistem operasi anda akan menguruskan sebahagian besar pekerjaan untuk anda dan KeyboardAvoidingView akan menguruskan selebihnya. Contoh AndroidManifest.xml. Selebihnya artikel ini kemungkinan tidak akan berlaku untuk anda.

SkrolView Papan Kekunci Papan Kekunci

Pilihan seterusnya ialah paparan reaksi-asli-papan kekunci-sedar-tatal yang memberi anda banyak keuntungan. Di sebalik tabir itu menggunakan ScrollView atau ListView untuk menangani semuanya (bergantung pada komponen yang anda pilih), yang menjadikan interaksi tatal cukup lancar. Manfaat utama lain untuk pakej ini ialah ia akan beralih ke input yang fokus, yang memberikan pengalaman yang menyenangkan kepada pengguna.

Penggunaan juga sangat mudah - anda hanya perlu menukar bekas View, sekali lagi bermula dengan kod asas, dan tetapkan beberapa pilihan. Inilah kodnya, maka saya akan menerangkannya.

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;

Mula-mula anda ingin menetapkan backgroundColor dari ScrollView dengan cara itu (jika anda mengaktifkan semula scrolling) backgroundColor selalu sama. Seterusnya anda ingin memberitahu komponen di mana kedudukan lalai adalah, setelah papan kekunci ditutup, ia kembali ke tempat itu - dengan menghilangkan alat ini, pandangan dapat tersekat di atas setelah menutup papan kekunci, seperti ini

Selepas alat resetScrollToCoords anda menetapkan contentContainerStyle - ini pada dasarnya menggantikan Viewgaya yang anda miliki sebelumnya. Perkara terakhir yang saya lakukan adalah melumpuhkan tatal tatal dari interaksi pengguna. Ini mungkin tidak selalu masuk akal untuk UI anda (seperti antara muka di mana pengguna mengedit banyak bidang profil) tetapi untuk yang ini, tidak masuk akal untuk membenarkan pengguna menatal secara manual kerana tidak ada apa-apa untuk menatal ke.

Menggabungkan alat peraga ini bersama-sama anda mendapat hasil berikut, yang berfungsi dengan baik.

Modul Papan Kekunci

Sejauh ini, ini adalah pilihan paling manual tetapi juga memberi anda kawalan yang paling banyak. Anda akan menggunakan perpustakaan Animasi untuk membantu memberikan interaksi yang lancar seperti yang anda lihat sebelumnya.

Modul Papan Kekunci, yang tidak didokumentasikan di laman React Native, membolehkan anda mendengar peristiwa papan kekunci yang dipancarkan dari peranti. Acara yang akan anda gunakan ialah keyboardWillShow dan keyboardWillHide , yang mengembalikan jangka masa animasi akan diambil dan kedudukan akhir papan kekunci (antara maklumat lain).

Sekiranya anda menggunakan Android, anda mahu menggunakan keyboardDidShow dan keyboardDidHide sebagai gantinya.

Apabila acara keyboardWillShow dipancarkan, anda akan menetapkan pemboleh ubah animasi ke ketinggian akhir papan kekunci dan menjadikannya beranimasi untuk tempoh yang sama dengan animasi gelongsor papan kekunci. Anda kemudian menggunakan nilai animasi ini untuk mengatur padding di bahagian bawah wadah untuk menambah semua kandungan.

Saya akan menunjukkan kod sebentar lagi, tetapi melakukan apa yang saya jelaskan di atas meninggalkan pengalaman ini.

Saya mahu membetulkan imej itu kali ini. Untuk melakukannya, anda akan menggunakan nilai animasi untuk mengatur ketinggian gambar, yang akan anda sesuaikan ketika papan kekunci dibuka. Inilah kodnya.

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;

Sudah tentu ada lebih banyak daripada penyelesaian lain. Daripada biasa Viewatau Imageanda menggunakan Animated.Viewdan Animated.Imagesupaya nilai animasi dapat dimanfaatkan. Bahagian yang menyeronokkan sebenarnya ada di keyboardWillShow dan keyboardWillHide berfungsi di mana nilai animasi berubah.

Apa yang berlaku di sana adalah bahawa dua nilai animasi berubah secara selari yang kemudian digunakan untuk mendorong UI. Itu meninggalkan anda dengan ini.

Ini lebih banyak kod tetapi cukup licin. Anda mempunyai banyak pilihan untuk apa yang boleh anda lakukan dan dapat menyesuaikan interaksi dengan isi hati anda.

Menggabungkan Pilihan

Sekiranya anda ingin menyimpan beberapa kod, anda boleh menggabungkan beberapa pilihan, itulah yang cenderung saya lakukan. Contohnya dengan menggabungkan pilihan 1 dan 3, anda hanya perlu risau untuk mengurus dan menghidupkan ketinggian gambar.

Kodnya tidak kurang daripada sumber pilihan 3 tetapi apabila UI bertambah dalam kerumitan, sedikit sebanyak dapat membantu anda.

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;

Setiap pelaksanaan mempunyai kebaikan dan keburukan - anda harus memilih yang paling sesuai dengan pengalaman pengguna yang anda inginkan.

Adakah anda berminat untuk mempelajari lebih lanjut mengenai penggunaan React Native untuk membina aplikasi mudah alih berkualiti tinggi? Daftar untuk kursus React Native percuma saya!