Cette bibliothèque résoudra ces problèmes :
Lorsque vous définissez windowSoftInputMode sur adjustNothing
, les événements React Native Keyboard, keyboardDidHide
et keyboardDidShow
, cesseront de fonctionner (voir le problème n° 2852).
Lorsque le clavier apparaît, tout le contenu de l'application monte (iOS et Android).
Pour les applications de chat qui doivent conserver la saisie du texte du bas dans la même position lorsque vous fermez le clavier et affichez certaines actions, le changement ne sera pas aussi fluide.
$ yarn add react-native-keyboard-area
Il est recommandé d'utiliser React Native > 0.60, la liaison automatique installera le module RNKeyboard
natif de cette bibliothèque pour iOS et Android.
Sur iOS : React Native fournit un composant appelé KeyboardAvoidingView
, enveloppez votre page avec celui-ci et il fera remonter le contenu lorsque le clavier apparaît.
Sur Android : par défaut, dans AndroidManifest.xml, le windowSoftInputMode est défini sur adjustResize
, tout le contenu de l'application sera déplacé vers le haut lorsque le clavier apparaîtra, nous n'aurons donc pas besoin du composant KeyboardAvoidingView
.
Dans les deux cas, le contenu entier de la page se déplacera vers le haut ou vers le bas, puis le clavier apparaîtra ou disparaîtra.
Mais parfois, nous n'avons pas besoin de toute l'application pour monter, l'exemple le plus courant est une application de chat, nous souhaiterons peut-être passer à une vue personnalisée lorsque le clavier disparaît.
Cette bibliothèque résout le problème en créant un composant wrapper KeyboardArea
, ce composant ajustera sa hauteur puis le clavier apparaîtra ou disparaîtra.
De plus, il est également possible de contrôler l'état avec les accessoires isOpen
ou avec les méthodes open()
et close()
exposées.
Un autre avantage est que ReactNaive ne repeindra pas l'intégralité de l'application lorsque le clavier apparaîtra, car la vue principale ne changera pas de taille.
Avant : En utilisant ReactNative KeyboardAvoidingView et ajusterResize, le résultat n'est pas très bon, la page "saute" quand le clavier disparaît après le switch | Après : En utilisant cette bibliothèque, la vue entière ne bougera pas et la zone du clavier sous la saisie gardera la même hauteur pendant le changement. |
Cette bibliothèque contient du code natif iOS et Android pour notifier, via un événement nommé KeyboardSizeChanges
, le composant KeyboardArea
lorsque la hauteur du clavier change.
Sur iOS, nous utilisons simplement le clavier UIResponder
et le clavierWillHideNotification pour ensuite émettre l'événement avec la hauteur actuelle.
Sur Android, nous devons définir windowSoftInputMode sur adjustNothing
, pour éviter que le clavier ne remonte toute la vue, puis nous créons une PopupWindow
invisible pour écouter les changements de disposition et mesurer la hauteur du clavier.
La majeure partie de la logique se trouve à l'intérieur du composant KeyboardArea
, nous devons simplement envelopper le contenu que nous voulons afficher lorsque le clavier disparaît, puis définir les accessoires isOpen lorsque nous devons afficher, dans le cas d'exemple suivant, le composant ChatActionsInput .
** ceci est une version simplifiée des captures d'écran ci-dessus **
import { KeyboardArea , KeyboardAreaRef } from 'react-native-keyboard-area' ;
/// ...
keyboardSpacerRef = createRef < KeyboardSpacerRef > ( ) ;
handleUserClick = ( ) => {
this . keyboardSpacerRef . current ?. close ( ) ;
}
handleChangeMode = ( ) => {
this . setState ( prev => ( {
inputMode :
prev . inputMode === ChatInputModes . Actions
? ChatInputModes . Text
: ChatInputModes . Actions ,
} ) ) ;
}
keyboardAreaHeightChanged = ( isOpen : boolean , currentHeight : number ) => {
// Your logic
} ;
render ( ) {
return (
< PageContent >
< ChatMessageList />
< ChatTextInput onChangeMode = { this . handleChangeMode } />
< KeyboardSpacer
ref = { this . keyboardSpacerRef }
isOpen = { inputMode === ChatInputModes . Actions }
onChange = { this . keyboardAreaHeightChanged }
>
< ChatActionsInput />
</ KeyboardSpacer >
</ PageContent >
) ;
}
Puisque sur Android, nous pourrions vouloir utiliser ajusterResize pour les autres pages, nous pouvons utiliser cette bibliothèque setWindowSoftInputMode
pour changer dynamiquement le mode SoftInput uniquement pour les pages dont nous avons besoin, par exemple :
import { RNKeyboard , SoftInputMode } from 'react-native-keyboard-area' ;
// Example with react-navigation page focus/blur events
componentDidMount ( ) {
navigation . addListener ( 'blur' , this . componentDidExit ) ;
navigation . addListener ( 'focus' , this . componentDidEnter ) ;
}
componentDidEnter = ( ) => {
if ( Platform . OS === 'android' ) {
RNKeyboard . setWindowSoftInputMode ( SoftInputMode . SOFT_INPUT_ADJUST_NOTHING , ) ;
}
} ;
componentDidExit = ( ) => {
if ( Platform . OS === 'android' ) {
RNKeyboard . setWindowSoftInputMode ( SoftInputMode . SOFT_INPUT_ADJUST_RESIZE ) ;
}
} ;
componentWillUnmount ( ) {
navigation . removeListener ( 'blur' , this . componentDidExit ) ;
navigation . removeListener ( 'focus' , this . componentDidEnter ) ;
}
Pour Android, tous les crédits reviennent à Cristian Holdunu et Siebe Brouwer pour la mise en œuvre de l'idée PopupWindow
et pour calculer la hauteur du clavier, je viens de le porter dans le système de modules React Native.