KeyboardAvoidingView - 隐藏键盘时重置高度

时间:2017-01-12 15:05:22

标签: javascript ios react-native keyboard

我在使用React Natives KeyboardAvoidingView设置键盘显示时View的高度。但是当我在应用程序中关闭键盘时,视图的高度不会更改回原来的值。

<KeyboardAvoidingView behavior="height" style={styles.step}>
  <View style={styles.stepHeader}>
    // my content
  </View>
</KeyboardAvoidingView>

在打开和关闭键盘之前,带有红色轮廓的视图占据了整个空间。

Screenshot

4 个答案:

答案 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子级的布局,因此请注意。