这个库将解决这些问题:
当将windowSoftInputMode设置为adjustNothing
时,React Native 键盘事件、 keyboardDidHide
和keyboardDidShow
将停止工作(请参阅问题#2852)。
当键盘出现时,整个应用程序内容将向上移动(iOS 和 Android)。
对于聊天应用程序来说,当关闭键盘并显示一些操作时,需要将底部文本输入保持在同一位置,切换不会那么顺利。
$ yarn add react-native-keyboard-area
建议使用 React Native > 0.60,自动链接将为 iOS 和 Android 安装此库本机RNKeyboard
模块。
在 iOS 上:React Native 提供了一个名为KeyboardAvoidingView
的组件,用它包裹你的页面,当键盘出现时它会向上移动内容。
在 Android 上:默认情况下,在AndroidManifest.xml中,我们将windowSoftInputMode设置为adjustResize
,当键盘出现时,整个应用程序内容将向上移动,因此我们不需要KeyboardAvoidingView
组件。
在这两种方式中,整个页面内容都会向上或向下移动,然后键盘出现或消失。
但有时我们不需要整个应用程序向上移动,最常见的例子是聊天应用程序,我们可能希望在键盘消失时切换到自定义视图。
这个库通过创建一个包装组件KeyboardArea
来解决这个问题,这个组件会调整他的高度,然后键盘出现或消失。
此外,还可以使用isOpen
属性或公开的open()
和close()
方法来控制状态。
另一个好处是,当键盘出现时,ReactNaive不会重新绘制整个应用程序,因为主视图不会改变大小。
之前:使用ReactNative KeyboardAvoidingView和调整Resize,结果不太好,切换后键盘消失时页面“跳转” | 之后:使用这个库后,整个视图不会移动,切换时输入下方的键盘区域会保持相同的高度 |
该库有一些 iOS 和 Android 本机代码,可在键盘高度发生变化时通过名为KeyboardSizeChanges
的事件通知KeyboardArea
组件。
在 iOS 上,我们仅使用UIResponder
KeyboardWillShowNotification 和 KeyboardWillHideNotification 来发出具有当前高度的事件。
在Android上我们需要将windowSoftInputMode设置为adjustNothing
,以避免键盘向上移动整个视图,然后我们创建一个不可见的PopupWindow
来监听布局变化并测量键盘高度。
大部分逻辑都在KeyboardArea
组件内部,我们只需要包装键盘消失时要显示的内容,然后在需要显示ChatActionsInput组件时设置isOpen属性,在下面的示例中。
** 这是上述屏幕截图的简化版本 **
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 上我们可能希望对其他页面使用 adjustmentResize,因此我们可以使用此库setWindowSoftInputMode
仅为我们需要的页面动态更改 SoftInput 模式,例如:
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 ) ;
}
对于 Android,所有功劳都归功于 Cristian Holdunu 和 Siebe Brouwer 的PopupWindow
想法实现以及计算键盘高度,我只是将其移植到 React Native 模块系统中。