【问题标题】:How to set the textinput box above the Keyboard while entering the input field in react nativereact native输入输入框时如何在键盘上方设置文本输入框
【发布时间】:2019-06-30 01:29:17
【问题描述】:

我正在使用 react-native TextInput 组件。如果用户点击 textInput 字段,这里我需要在键盘上方显示 InputBox。

我在下面尝试过,但我遇到了问题

1.键盘避免视图

 a. Here it shows some empty space below the input box 
 b. Manually I need to scroll up the screen to see the input field which I was given in the text field
 c. Input box section is hiding while placing the mouse inside the input box 

2。 react-native-Keyboard-aware-scroll-view

a.It shows some empty space below the input box
b.ScrollView is reset to the top of the page after I moving to the next input box

这里我在 ScrollView 组件中设置了 Keyboard-aware-scroll-view

请澄清

我的示例代码是

<SafeAreaView>
<KeyboardAvoidingView>
<ScrollView>        
        <Text>Name</Text>
            <AutoTags
            //required
             suggestions={this.state.suggestedName}
             handleAddition={this.handleAddition}
             handleDelete={this.handleDelete}
             multiline={true}
             placeholder="TYPE IN"
             blurOnSubmit={true}
             style= {styles.style}
             />
</ScrollView>   
</KeyboardAvoidingView>
</SafeAreaView>

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

【问题讨论】:

  • 尝试为 KeyboardAvoidingView 设置 behviour,并确保您的 contianer 视图样式为 flex
  • 我为 KeyboardAvoidingView 设置了 behavior = 'padding' style = {{flex:1 }}。 NAME placeholder="TYPE IN"/>
  • 我在 react native 中需要这种类似的行为。移动到文本输入框时,键盘打开并在返回后关闭。github.com/Just-/UIViewController-KeyboardAnimation
  • 你能试着去掉&lt;View&gt;标签,在&lt;KeyboardAvoidingView&gt;外面放一个吗?
  • 不知道你为什么回滚我的编辑。如果您可以将代码放在问题描述中,那肯定会有所帮助。

标签: react-native textbox keyboard-events textinput


【解决方案1】:

给你的 TextInput 一个位置:绝对样式,并使用由 keyboardDidShow 和 keyboardDidHide 事件返回的高度来改变它的位置。

这里是来自 React Native documentation 的键盘示例的修改,用于演示:

import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';

class Example extends Component {
    state = {
        keyboardOffset: 0,
    };

    componentDidMount() {
        this.keyboardDidShowListener = Keyboard.addListener(
            'keyboardDidShow',
            this._keyboardDidShow,
        );
        this.keyboardDidHideListener = Keyboard.addListener(
            'keyboardDidHide',
            this._keyboardDidHide,
        );
    }

    componentWillUnmount() {
        this.keyboardDidShowListener.remove();
        this.keyboardDidHideListener.remove();
    }

    _keyboardDidShow(event) {
        this.setState({
            keyboardOffset: event.endCoordinates.height,
        })
    }

    _keyboardDidHide() {
        this.setState({
            keyboardOffset: 0,
        })
    }

    render() {
        return <View style={{flex: 1}}>
            <TextInput
                style={{
                    position: 'absolute',
                    width:    '100%',
                    bottom:   this.state.keyboardOffset,
                }}
                onSubmitEditing={Keyboard.dismiss}
            />
        </View>;
    }
}

【讨论】:

  • 我已经尝试过了。但它在 AutoTags 中没有像我预期的那样工作
  • 嗨,我正在尝试上面的代码,但我注意到页面内容,在我的例子中是 FlatList 跳转 cuz bottom: this.state.keyboardOffset。另外,event.endCoordinates.height 的返回值似乎比键盘高,因为TextInputKeyboard 之间存在差距。
  • @Yasir "absolute" 定位元素是相对于它们的包含视图而言的,它的大小可能与设备不同。如果您的 TextInput 位于小于设备高度的容器内,则需要考虑容器和设备之间的高度差异。这是一个对我来说可以将“文本”视图直接放置在键盘上方的公式:bottom: keyboardHeight - ((deviceHeight - containerHeight) / 2)。我有一个顶部和底部栏,我的文本视图在一个容器中,所以我考虑了设备高度和我的容器之间的差异。
【解决方案2】:

挂钩版本:

const [keyboardOffset, setKeyboardOffset] = useState(0);
const onKeyboardShow = event => setKeyboardOffset(event.endCoordinates.height);
const onKeyboardHide = () => setKeyboardOffset(0);
const keyboardDidShowListener = useRef();
const keyboardDidHideListener = useRef();

useEffect(() => {
  keyboardDidShowListener.current = Keyboard.addListener('keyboardWillShow', onKeyboardShow);
  keyboardDidHideListener.current = Keyboard.addListener('keyboardWillHide', onKeyboardHide);

  return () => {
    keyboardDidShowListener.current.remove();
    keyboardDidHideListener.current.remove();
  };
}, []);

【讨论】:

  • 就我而言,keyboardDidShow & keyboardDidHide 事件有效。
【解决方案3】:

你可以使用KeyboardAvoidingView如下

if (Platform.OS === 'ios') {
        return <KeyboardAvoidingView behavior="padding">
            {this.renderChatInputSection()}
        </KeyboardAvoidingView>
    } else {
        return this.renderChatInputSection()
    }

this.renderChatInputSection() 将返回类似于 textinput 的视图用于输入消息。希望这会对你有所帮助。

【讨论】:

【解决方案4】:

首先,您不需要任何额外的 Android 平台代码。 只需将您的输入保存在 ScrollView 中。 iOS 平台只需使用KeyboardAvoidingView 封装ScrollView

创建如下函数来保存所有输入

renderInputs = () => {
    return (<ScrollView
        showsVerticalScrollIndicator={false}
        style={{
            flex: 1,
        }}
        contentContainerStyle={{
            flexGrow: 1,
        }}>
        <Text>Enter Email</Text>
        <TextInput
            style={styles.text}
            underlineColorAndroid="transparent"
        />
    </ScrollView>)
}

然后将它们呈现在主视图中,如下所示

{Platform.OS === 'android' ? (
    this.renderInputs()
) : (
    <KeyboardAvoidingView behavior="padding">
        {this.renderInputs()}
    </KeyboardAvoidingView>
)}

我已经使用过这种方法,我可以保证它有效。 如果它不起作用,那么您可能会遗漏一些东西。

【讨论】:

    【解决方案5】:

    对于android你可以在AndroidManifest文件中为Activity设置android:windowSoftInputMode="adjustResize",这样当键盘显示时,你的屏幕会调整大小,如果你把TextInput放在屏幕底部,它将保持键盘上方

    【讨论】:

    • 那么 iOS 呢?
    【解决方案6】:

    react-native-keyboard-aware-scroll-view 在 ios 中引起了类似的问题。就在那时我遇到了react-native-keyboard-aware-view。片段几乎相同。

        <KeyboardAwareView animated={true}>
            <View style={{flex: 1}}>
              <ScrollView style={{flex: 1}}>
                  <Text style={{fontSize: 20, color: '#FFFFFF'}}>A</Text>
                  <Text style={{fontSize: 20, color: '#FFFFFF'}}>B</Text>
                  <Text style={{fontSize: 20, color: '#FFFFFF'}}>C</Text>
                  <Text style={{fontSize: 20, color: '#FFFFFF'}}>D</Text>
              </ScrollView>
            </View>
            <TouchableOpacity style={{height: 50, backgroundColor: 'transparent', alignItems: 'center', justifyContent: 'center', alignSelf: 'stretch'}}>
              <Text style={{fontSize: 20, color: '#FFFFFF'}}>Submit</Text>
            </TouchableOpacity>
          </KeyboardAwareView>
    

    希望对你有帮助

    【讨论】:

    • 这里不是文本。从 react-native autoTags 渲染的 TextInput 框
    【解决方案7】:

    你一定会发现这很有用

    Keyboard aware scroll view Android issue

    我真的不知道你为什么要添加

    "androidStatusBar": { “背景颜色”:“#000000” }

    让 KeyboardawareScrollview 工作

    注意:不要忘记在没有最后一步的情况下重新启动项目,它可能无法正常工作 享受吧!

    【讨论】:

      【解决方案8】:

      我在处理我的业余项目时遇到了同样的问题,我在稍微调整了 KeyboardAvoidingView 后解决了这个问题。 我将my solution 发布到 npm,请试一试并给我反馈! Demo on iOS

      示例代码段

      import React from 'react';
      import { StyleSheet, TextInput } from 'react-native';
      import KeyboardStickyView from 'rn-keyboard-sticky-view';
      
      const KeyboardInput = (props) => {
        const [value, setValue] = React.useState('');
      
        return (
          <KeyboardStickyView style={styles.keyboardView}>
            <TextInput
              value={value}
              onChangeText={setValue}
              onSubmitEditing={() => alert(value)}
              placeholder="Write something..."
              style={styles.input}
            />
          </KeyboardStickyView>
        );
      }
      
      const styles = StyleSheet.create({
        keyboardView: { ... },
        input: { ... }
      });
      
      export default KeyboardInput;

      【讨论】:

        【解决方案9】:

        我的解决方案基于@basbase 解决方案。

        我对他的解决方案的问题是,它使 TextInput 跳了起来,而不考虑我的整体观点。

        这不是我想要的,所以我按照他的建议做了,但做了一些小改动

        只需像这样给父视图样式:

         <View 
                     style={{
                      flex: 1,
                      bottom:   keyboardOffset,
                  }}>
        

        它会起作用的!唯一的问题是,如果键盘打开并且向下滚动,您会在屏幕末尾看到额外的空白填充。

        【讨论】:

          【解决方案10】:

          转到你的 Android>app>src>main> AndroidManifest.xml 写下这两行:

          android:launchMode="singleTop" android:windowSoftInputMode="adjustPan"

          【讨论】:

            【解决方案11】:

            最好最简单的方法是使用滚动视图,它会自动将内容向上取并且不会隐藏文本输入,可以参考下面的代码

              <ScrollView style={styles.container}>
              <View>
                <View style={styles.commonView}>
                  <Image source={firstNameIcon} style={{width: 25, height: 25}}></Image>
                  <Text style={styles.commonTxt}>First Name</Text>
                </View>
            
                <TextInput
                  onFocus={() => onFocus('firstName')}
                  placeholder="First Name"
                  style={styles.txtInput}
                  onChangeText={(text) => onChangeText(text, 'firstName')}
                  value={firstNameValue}
                />
              </View>
              <View>
                <View style={styles.commonView}>
                  <Image source={LastNameIcon} style={{width: 25, height: 25}}></Image>
                  <Text style={styles.commonTxt}>Last Name</Text>
                </View>
            
                <TextInput
                  onFocus={() => onFocus('lastName')}
                  placeholder="Last Name"
                  style={styles.txtInput}
                  onChangeText={(text) => onChangeText(text, 'lastName')}
                  value={lastNameValue}
                />
              </View>
              <View>
                <View style={styles.commonView}>
                  <Image source={callIcon} style={{width: 25, height: 25}}></Image>
                  <Text style={styles.commonTxt}>Number</Text>
                </View>
            
                <TextInput
                  onFocus={() => onFocus('number')}
                  placeholder="Number"
                  style={styles.txtInput}
                  onChangeText={(text) => onChangeText(text, 'number')}
                  value={numberValue}
                />
              </View>
              <View>
                <View style={styles.commonView}>
                  <Image source={emailIcon} style={{width: 25, height: 25}}></Image>
                  <Text style={styles.commonTxt}>Email</Text>
                </View>
            
                <TextInput
                  onFocus={() => onFocus('email')}
                  placeholder="Email"
                  style={styles.txtInput}
                  onChangeText={(text) => onChangeText(text, 'email')}
                  value={emailValue}
                />
              </View>
            
              <View style={styles.viewSavebtn}>
                <TouchableOpacity style={styles.btn}>
                  <Text style={styles.saveTxt}>Save</Text>
                </TouchableOpacity>
              </View>
            </ScrollView>
            

            【讨论】:

              猜你喜欢
              • 2013-12-05
              • 1970-01-01
              • 2016-09-21
              • 1970-01-01
              • 2012-04-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多