react-native-keyboard-area
v1.0.6
Published
React Native component that provides a View that always match the height of the keyboard
Downloads
2,001
Maintainers
Readme
react-native-keyboard-area
This library will address these problems:
When set windowSoftInputMode to
adjustNothing
, the React Native Keyboard events,keyboardDidHide
andkeyboardDidShow
, will stop working (see issue #2852).When Keyboard appear the entire app content will move up (iOS and Android).
For chat application than needs to keep the bottom text input in the same position when dismiss the Keyboard and show some actions, the switch will not be that smooth.
Getting started
$ yarn add react-native-keyboard-area
Is recommend to use React Native > 0.60, the autolinking will install this library native RNKeyboard
module for iOS and Android.
Introduction
On iOS: React Native provides a component called
KeyboardAvoidingView
, wrap your page with that and it will move up the content when the keyboard appears.On Android: By default in the AndroidManifest.xml we have the windowSoftInputMode set to
adjustResize
, the entire app content will move up when the keyboard appears so we don't need theKeyboardAvoidingView
component.
In both way, the entire page content will move up or down then the Keyboard appear or disappear.
But sometimes we don't need to whole app to move up, the most common example is a Chat application, we might want to switch to a Custom View when the keyboard disappear.
Here comes this Library
This library solve the problem by creating a wrapper component KeyboardArea
, this component will adjust his height then the keyboard appear or disappear.
In addition is also possible to control the state with isOpen
props or with the exposed open()
and close()
methods.
Another benefit is that the ReactNaive will not repaint the whole app when the keyboard appears since main view will not change is size.
Real world example: before and after
How it works?
This library have some iOS and Android native code to notify, through an event named KeyboardSizeChanges
, the KeyboardArea
component when the keyboard height changes.
On iOS we just use the
UIResponder
keyboardWillShowNotification and keyboardWillHideNotification to then emit the event with the current height.On Android we need to set the windowSoftInputMode to
adjustNothing
, to avoid the keyboard to move up the entire view, then we create a invisiblePopupWindow
to listen the layout changes and measure the keyboard height.
Usage
Most of the logic is inside the KeyboardArea
component, we just need to wrap the content we want to show when the keyboard disappear and then set the isOpen props when we need to show, in follow example case, the ChatActionsInput component.
** this is a simplified version of the above screenshots **
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>
);
}
Android notes
Since on android we might want use adjustResize for the others page, we can use this library setWindowSoftInputMode
to dynamically change the SoftInput mode only for the pages that we need, for example:
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);
}
Credits
For Android all credits goes to Cristian Holdunu and Siebe Brouwer for the PopupWindow
idea implementation and to calculate the keyboard height, I just port it in the React Native module system.