如何在 React Native 中检测键盘何时打开或关闭
Posted
技术标签:
【中文标题】如何在 React Native 中检测键盘何时打开或关闭【英文标题】:How to detect when keyboard is opened or closed in React Native 【发布时间】:2019-01-07 10:05:13 【问题描述】:如何检测用户是否在本机反应中关闭键盘,我想在用户关闭键盘时调用一个函数。
如果您能回答以检测键盘是否打开,我们将不胜感激,谢谢。
我在 react native 最新 version 0.56
【问题讨论】:
【参考方案1】:1。您可以使用来自 facebook 的 Keyboard class。
这是一个示例代码。
import React, Component from 'react';
import Keyboard, TextInput from 'react-native';
class Example extends Component
componentWillMount ()
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
componentWillUnmount ()
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
_keyboardDidShow ()
alert('Keyboard Shown');
_keyboardDidHide ()
alert('Keyboard Hidden');
render()
return (
<TextInput
onSubmitEditing=Keyboard.dismiss
/>
);
###2。您也可以使用其他一些 npm 依赖项,例如 react-native-keyboard-listener。
将组件导入到你要使用的文件中:
import KeyboardListener from 'react-native-keyboard-listener';
直接在您的代码中使用该组件。该组件不会渲染任何东西
<View>
<KeyboardListener
onWillShow=() => this.setState( keyboardOpen: true );
onWillHide=() => this.setState( keyboardOpen: false );
/>
</View>
要安装此依赖项,请运行以下命令。
npm install --save react-native-keyboard-listener
选择任何你觉得更方便的。
【讨论】:
第一个我希望它像超人一样工作:D 谢谢人。 @Khemraj 为什么我不能在函数 _keyboardDidShow 或 _keyboardDidHide 中设置状态? @Khemraj 需要注意的是,选项 2 不再适用于 android 我在我的应用程序中添加了Keyboard.addListener('keyboardDidShow', alert('keyboard'));
,它一打开就会触发。在网络视图和我的 Android 设备上都是一样的。任何想法我做错了什么?
@stefanS 是的。 alert('keyboard')
在您绑定处理程序时正在执行。要在触发处理程序时触发警报,请使用 Keyboard.addListener('keyboardDidShow', () => alert('keyboard'));
【参考方案2】:
@Khemraj 答案的改进版本(对我来说非常有用),将方法绑定到实例,以便能够从侦听器更新组件的状态并重新渲染。
import React, Component from 'react';
import Keyboard, TextInput from 'react-native';
class Example extends Component
state =
keyboardState: 'closed'
componentWillMount ()
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
componentWillUnmount ()
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
_keyboardDidShow = () =>
this.setState(
keyboardState: 'opened'
);
_keyboardDidHide = () =>
this.setState(
keyboardState: 'closed'
);
render()
return (
<TextInput
onSubmitEditing=Keyboard.dismiss
/>
);
【讨论】:
【参考方案3】:谢谢你们的回答。如果有人感兴趣,这里是钩子版本:
const [isKeyboardVisible, setKeyboardVisible] = useState(false);
useEffect(() =>
const keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
() =>
setKeyboardVisible(true); // or some other action
);
const keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() =>
setKeyboardVisible(false); // or some other action
);
return () =>
keyboardDidHideListener.remove();
keyboardDidShowListener.remove();
;
, []);
【讨论】:
嗨@5-10。我在我的应用程序中使用了这个确切的代码,但由于某种原因,这两个事件都没有被触发。我在清单文件中使用带有android:windowSoftInputMode="adjustResize"
的RN 版本0.63.4。什么可能导致它无法正常运行?谢谢。
在 RN 0.63.4 上按预期工作,没有任何清单更改。
当我尝试这个时,我得到以下错误:ReferenceError: Can't find variable: useEffect
,有什么原因吗?
有点晚了,但@yem 你需要:import React, useEffect, useState from "react"
和 import Keyboard from "react-native"
【参考方案4】:
MobX 版本:
import observable from 'mobx'
import EmitterSubscription, Keyboard from 'react-native'
class KeyboardStore
@observable isKeyboardVisible = false
keyboardSubs: EmitterSubscription[] = []
subKeyboard()
this.keyboardSubs = [
Keyboard.addListener('keyboardDidShow', () => this.isKeyboardVisible = true),
Keyboard.addListener('keyboardDidHide', () => this.isKeyboardVisible = false),
]
unsubKeyboard()
this.keyboardSubs.forEach(sub => sub.remove())
this.keyboardSubs = []
在*** App 组件内部
useEffect(() =>
store.subKeyboard()
return () =>
store.unsubKeyboard()
, [])
并使用store.isKeyboardVisible
检查您应用中的任何位置。
【讨论】:
【参考方案5】:所有已经在 react-native Keyboard
类中可用的东西
import React, Component from 'react';
import Keyboard, TextInput from 'react-native';
class Example extends Component
componentDidMount()
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
this.keyboardWillShowListener = Keyboard.addListener('keyboardWillShow', this._keyboardWillShow);
this.keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', this._keyboardWillHide);
componentWillUnmount()
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
this.keyboardWillShowListener.remove();
this.keyboardWillHideListener.remove();
_keyboardWillShow()
console.log('Keyboard Showning')
_keyboardWillHide()
console.log('Keyboard Heding')
_keyboardDidShow()
alert('Keyboard Shown');
_keyboardDidHide()
alert('Keyboard Hidden');
render()
return (
<TextInput
onSubmitEditing=Keyboard.dismiss
/>
);
【讨论】:
【参考方案6】:自定义挂钩:
import useEffect, useState from 'react';
import Keyboard from 'react-native';
export function useKeyboard()
const [isKeyboardVisible, setKeyboardVisible] = useState(false);
useEffect(() =>
const keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
() =>
setKeyboardVisible(true); // or some other action
,
);
const keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() =>
setKeyboardVisible(false); // or some other action
,
);
return () =>
keyboardDidHideListener.remove();
keyboardDidShowListener.remove();
;
, []);
return isKeyboardVisible;
用法:
import useKeyboard from './useKeyboard';
const isKeyBoardOpen = useKeyboard();
【讨论】:
完美。谢谢【参考方案7】:我在@react-native-community/hooks 中发现了usekeyboard 钩子
例如
import useKeyboard from '@react-native-community/hooks'
const keyboard = useKeyboard()
console.log('keyboard isKeyboardShow: ', keyboard.keyboardShown)
console.log('keyboard keyboardHeight: ', keyboard.keyboardHeight)
来源:https://github.com/react-native-community/hooks/blob/master/src/useKeyboard.ts
【讨论】:
很好的解决方案,但获取当前键盘状态似乎有延迟以上是关于如何在 React Native 中检测键盘何时打开或关闭的主要内容,如果未能解决你的问题,请参考以下文章
键盘打开时TextInput不可见Expo React Native
使用React Native的MapView,我如何确定何时到达最终拖动目的地?