无法弄清楚如何正确使用 KeyboardAvoidingView

Posted

技术标签:

【中文标题】无法弄清楚如何正确使用 KeyboardAvoidingView【英文标题】:Can't figure out how to properly use KeyboardAvoidingView 【发布时间】:2019-10-26 07:20:11 【问题描述】:

我正在使用 react native 开发一个应用程序,我们有设计师制作的屏幕布局。但我无法正确实现预期的行为。基本上它是一个带有一些文本输入和一个按钮的屏幕,当键盘出现时我需要正确调整东西。以下是预期的屏幕:

所以当键盘出现时,按钮必须向上很多,两个文本输入都会上升一点,顶部的文本保持不变。没有键盘的屏幕看起来很完美,但现在当键盘出现时它什么也不做。我尝试了很多东西,都没有真正奏效。现在是渲染方法:

render() 
    const textInputBorderColor = this.state.hasError ? Colors.error : Colors.background;
    const textInputCpfMarginTop = this.state.hasError ? 24 : 48;

    return (
        <View style = styles.container>
            <KeyboardAvoidingView behavior='padding'>
                <Text style = styles.headerText>Vamos começar!</Text>
                
                <TextInput 
                    value = this.props.user.name 
            onChangeText = text => this.props.user.name = text
                    placeholder = 'Insira aqui seu nome completo'
                    style = [styles.textInputName, borderColor: textInputBorderColor]
                />

                <ErrorText show = this.state.hasError value = this.state.errorMsg/>

                <TextInputMask
                    value = this.props.user.cpf
                    onChangeText = text => this.props.user.cpf = text
                    placeholder = 'e aqui seu CPF'
                    keyboardType = 'numeric'
                    type = 'cpf'
                    style = [styles.textInputCpf, borderColor: Colors.background, marginTop: textInputCpfMarginTop]
                />
            
                <View style = marginTop: 202>
                    <DefaultButton 
                        onPress = this.onButtonPress
                        btnLabel = 'Continuar'
                        disabled = (this.props.user.name == '' || this.props.user.cpf.length != 14)
                    />
                </View>
            </KeyboardAvoidingView>
        </View>
    );

样式:

const styles = StyleSheet.create(
    container: 
        flex: 1,
        backgroundColor: '#FFFFFF',
        alignItems: 'center',
    ,

    textInputName: 
        textAlign: 'center',
        fontFamily: 'Roboto-Light',
        fontSize: 16,
        paddingBottom: ScreenDimensions.width * 0.01,
        borderBottomWidth: 1,
        marginTop: 96,
        width: 321
    ,

    textInputCpf: 
        textAlign: 'center',
        fontFamily: 'Roboto-Light',
        fontSize: 16,
        paddingBottom: ScreenDimensions.width * 0.01,
        borderBottomWidth: 1,
        width: 321
    ,
    
    headerText: 
        marginTop: 66,
        textAlign: 'center',
        fontFamily: 'Roboto-Light',
        fontSize: 20,
        color: '#000'
    
)

关于这个组件(keyboardAvoidingView)的文档一文不值……

非常感谢您的帮助!

【问题讨论】:

您是否厌倦了将按钮放在键盘外以避免查看? 是的,还是什么都没有:/ 您是否也尝试将flex:1 添加到KeyboardAvoidingView 中?在我看来,你甚至不需要最外面的&lt;View&gt;,只需将容器样式传递给KeyboardAvoidingView,它应该是一样的 是的,最外面的视图是不需要的,但仍然没有,我只是添加了一个滚动视图来帮助用户。 【参考方案1】:

忘记发布对我们有用的内容。经过一些测试,我们能够找到一个可行的解决方案。我们将文本输入包围在ScrollView 中,因此在使用小屏幕设备时它可以正常工作,并且只用KeyboardAvoidingView 包围按钮。两者都被外部View包围。

这是一个例子:

<View style = flex: 1, alignItems: 'center', justifyContent: 'flex-end'>
  <ScrollView 
    contentContainerStyle= flexGrow: 1, justifyContent: 'center' 
    style= alignSelf: 'stretch' 
  >
    # Your Text Inputs
  </ScrollView>

  <KeyboardAvoidingView
    behavior='padding'
    keyboardVerticalOffset=Platform.OS == 'ios' ? Header.HEIGHT + getStatusBarHeight() : Header.HEIGHT + 32
    style= flex: 1, justifyContent: 'flex-end', alignSelf: 'stretch', marginBottom: 16 
  >
    # Yout Button
  </KeyboardAvoidingView>
</View>

旁注:在 ScrollViews 中使用文本输入和按钮时要小心(我的解决方案不是这种情况),因为存在一个小问题,您无法使用键盘单击按钮打开。

【讨论】:

如果您需要将文本输入和按钮放在同一个 ScrollView 中(这很常见),您可以使用 keyboardShouldPersistTaps='handled' 修复子级点击处理。更多信息可以查看documentation【参考方案2】:

试试这个:

const keyboardAvoidingViewBehaviour = (Platform.OS === 'ios') ? 'padding' : null;

使用KeyboardAvoiding视图作为根组件,不需要额外的视图。

        <KeyboardAvoidingView 
           behavior=keyboardAvoidingViewBehaviour
           style = styles.container // <-- have flex: 1 as one of the style props here
        >
            <Text style = styles.headerText>Vamos começar!</Text>

            <TextInput
            // ...

如果您的内容需要滚动,一个不错的选择是:

react-native-keyboard-aware-scroll-view

https://github.com/APSL/react-native-keyboard-aware-scroll-view

【讨论】:

现在我使用的是滚动视图,它可以工作,但不是我想要的

以上是关于无法弄清楚如何正确使用 KeyboardAvoidingView的主要内容,如果未能解决你的问题,请参考以下文章

无法弄清楚如何使用 CLPlacemark 将我当前的位置正确嵌入到消息正文中

C++:无法弄清楚如何正确隐藏实现细节

无法弄清楚如何正确设置 DropdownButton 的样式

无法弄清楚如何让 CMake 为自定义 clang 驱动程序提取正确的标头

无法弄清楚为啥我的提交按钮不会提交

使用带有类的重载函数,无法弄清楚垃圾来自哪里