這個庫將解決這些問題:
當將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 模組系統中。