我在使用React Natives KeyboardAvoidingView
设置键盘显示时View
的高度。但是当我在应用程序中关闭键盘时,视图的高度不会更改回原来的值。
<KeyboardAvoidingView behavior="height" style={styles.step}>
<View style={styles.stepHeader}>
// my content
</View>
</KeyboardAvoidingView>
在打开和关闭键盘之前,带有红色轮廓的视图占据了整个空间。
答案 0 :(得分:20)
关于Nisarg答案的更详细解释。
在构造函数
中为KeyboardAvoidingView
创建一个键
constructor(props) {
this.state = {
keyboardAvoidingViewKey: 'keyboardAvoidingViewKey',
}
}
在键盘上添加监听器将会/隐藏(并在willUnmount中删除它)
import { KeyboardAvoidingView, Keyboard, Platform } from 'react-native'
componentDidMount() {
// using keyboardWillHide is better but it does not work for android
this.keyboardHideListener = Keyboard.addListener(Platform.OS === 'android' ? 'keyboardDidHide': 'keyboardWillHide', this.keyboardHideListener.bind(this));
}
componentWillUnmount() {
this.keyboardHideListener.remove()
}
更新keyboardAvoidingViewKey
函数中的keyboardHideListener
,每次都应该是一个新值(我使用了时间戳),并在呈现KeyboardAvoidingView
元素时使用此键。
keyboardHideListener() {
this.setState({
keyboardAvoidingViewKey:'keyboardAvoidingViewKey' + new Date().getTime()
});
}
render() {
let { keyboardAvoidingViewKey } = this.state
return (
<KeyboardAvoidingView behavior={'height'} key={keyboardAvoidingViewKey} style={...}>
...
</KeyboardAvoidingView>
)
}
注意:强>
请记住,这将重新创建KeyboardAvoidingView
内的元素(即:将调用他们的constructor
函数,我不太清楚为什么,我会在深入调查后更新答案),所以你将不得不跟踪可能被覆盖的任何州/道具值
经过更深入的调查后,我现在知道为什么在更改密钥后会重新创建视图。
为了真正理解它为什么会发生,我们必须熟悉react-native如何将渲染命令调度到本机端,这个特殊的解释很长,如果它感兴趣,你可以阅读我的答案here。简而言之,react-native使用Reactjs来区分应该呈现的更改,然后将这些diff作为命令发送到名为UIManager
的组件,该组件发送转换为布局树的命令式命令,该布局树更改基于布局关于diff命令。
在组件上设置密钥后,reactjs使用此密钥来识别对所述组件的更改,如果此密钥更改,reactjs将该组件标识为一个全新的组件,然后发送初始命令以创建所述组件,使其全部成为要从头开始创建子项,因为在新布局树中将其标识为新元素,删除旧树并创建新树而不是仅调整差异
如果您愿意,您可以通过将以下代码添加到App.js
文件来实际监视这些已发送的邮件:
import MessageQueue from 'react-native/Libraries/BatchedBridge/MessageQueue'
const spyFunction = (msg) => {
console.log(msg);
};
MessageQueue.spy(spyFunction);
如果你这样做,你会在日志中注意到每次密钥更改时,返回的命令都是createViews
,如上所述,它会创建嵌套在所述组件下的所有元素
答案 1 :(得分:7)
请键盘给KeyboardAvoidingView并在键盘打开和关闭时更改,以便渲染并占据高度
<KeyboardAvoidingView behavior="height" style={styles.step} key={values}>
答案 2 :(得分:1)
在iOS的<KeyboardAvoidingView behavior="padding" style={styles}>
和Android的<View style={styles}>
中包装组件
render() {
const ScrollContainer: View | KeyboardAvoidingView =
this.renderDependingOnPlatform();
const scrollContainerParams: any = {};
if (isIOS)
scrollContainerParams.behavior = "padding";
return (
<ScrollContainer style={styles.container} {...scrollContainerParams}>
Scroll and other components
</ScrollContainer>
)}
/**
* Render scroll container depending on platform
* @returns {any}
*/
renderDependingOnPlatform() {
if (isAndroid())
return View;
else return KeyboardAvoidingView;
}
答案 3 :(得分:0)
一个简单的解决方法是将behavior
的{{1}}属性设置为'padding'。这样就避免了调用KeyboardAvoidingView
函数的问题,该函数使您可以安全地将信息存储在状态中(例如,您有两个constructor
,并且即使用户使用,也要以状态存储文本的值)在单击两个输入之间使键盘折叠)。
此方法可能会稍微改变Input
子级的布局,因此请注意。