【问题标题】:React-native how to move screen up on textinputReact-native如何在文本输入上向上移动屏幕
【发布时间】:2015-08-13 07:59:52
【问题描述】:

我有一个使用 react-native 创建的登录屏幕。

当用户在 textInput 中输入时,如何将屏幕向上移动?

我是否监听 onFocus() 事件并使用 css 样式来更改视图的样式?

【问题讨论】:

标签: javascript reactjs react-native


【解决方案1】:

您可以使用ScrollView 来控制屏幕上下移动。只要用户没有关注任何TextInput,您就可以disable scroll。在焦点上,只需使用 Content Offset 属性向上移动滚动视图。

<TextInput
    onFocus={this.textInputFocused.bind(this)}
  />

textInputFocused() {
//do your stuff here. scroll screen up
}

希望对你有帮助!

【讨论】:

    【解决方案2】:

    Night Fury 的回答很不错,虽然不会对 ScrollView 的 contentOffset 大惊小怪,我会使用 ScrollResponder

    render() {
      return (
        <ScrollView ref="myScrollView">
          <TextInput
            ref="myInput"
            onFocus={this._scrollToInput.bind(this)}
          />
        </ScrollView>
      );
    }
    
    _scrollToInput {
      const scrollResponder = this.refs.myScrollView.getScrollResponder();
      const inputHandle = React.findNodeHandle(this.refs.myInput)
    
      scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
        inputHandle, // The TextInput node handle
        0, // The scroll view's bottom "contentInset" (default 0)
        true // Prevent negative scrolling
      );
    }
    

    查看方法定义:scrollResponderScrollNativeHandleToKeyboard

    【讨论】:

    • 这将在 getScrollResponder 上失败我猜这是在旧版本的 api 上工作的。我使用 scrollTo 并对数字进行硬编码,这是一个糟糕的解决方案,我很想将 webviews 用于表单页面。
    • 上移屏幕效果很好,输入完后我应该用什么再次下移屏幕?
    【解决方案3】:

    还有另一个解决方案,使用 RN 0.2,这次不是压缩它滚动的内容。

     inputFocused: function(ref) {
       this._scroll(ref, 75);
     },
    
     inputBlurred: function(ref) {
       this._scroll(ref, 0);
     },
    
     _scroll: function(ref, offset) {
       setTimeout(() => {
         var scrollResponder = this.refs.myScrollView.getScrollResponder();
         scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
                    React.findNodeHandle(this.refs[ref]),
                    offset,
                    true
                );
         });
      },
    

    ...

    render: function() {
      return <View style={{flex: 1}}> 
        <ScrollView ref="myScrollView" keyboardDismissMode='interactive' contentContainerStyle={{flex: 1}}>
          <TextInput
            ref="myInput"
            onFocus={this.inputFocused.bind(this, 'myInput')}
            onBlur={this.inputBlurred.bind(this, 'myInput')} />
        </ScrollView>
      </View>
    }
    

    【讨论】:

      【解决方案4】:

      这个package 做得很好,引入了一个 KeyboardAwareScrollView 组件,该组件可以向上滚动视图以匹配键盘输入,然后向下滚动。

      【讨论】:

        【解决方案5】:

        2017 年 (RN 0.43) 有专门的组件:KeyboardAvoidingView

        【讨论】:

        • @farmcommand2 它可以工作,但有一些技巧。 GitHub 上有issue 提供解决方案。我用这个:behavior={(Platform.OS === 'ios') ? 'padding' : null}
        • 有点蹩脚。我宁愿自己实现键盘事件。所以你确实可以控制布局的行为
        • 截至 2018 年 12 月,它似乎也适用于 Android。
        • 不幸的是,KeyboardAvoidingView 是一个纯粹的垃圾,并没有真正起作用。
        【解决方案6】:

        让 ScrollView 的本机键盘感知功能正常工作是个废话。对于我的 Android 应用程序,它可以在一个屏幕上完美运行,而另一个屏幕几乎与另一个不工作的屏幕相同。而在 iOS 上,它就是行不通的。这对我有用:

        import { Keyboard, ScrollView, StyleSheet, View } from 'react-native';
        
        this.state = {
            filler: false,
        }
        
        componentWillMount() {
            this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
            this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
        }
        
        componentWillUnmount() {
            this.keyboardDidShowListener.remove();
            this.keyboardDidHideListener.remove();
        }
        
        _keyboardDidShow() {
            this.setState({filler: true})
            setTimeout(() => this.vertical && this.vertical.scrollToEnd({animated: true}), 0);
        }
        
        _keyboardDidHide() {
            this.setState({filler: false})
        }
        
        
        ...
        return (
          <ScrollView ref={ref => this.vertical = ref}>
            <TextInput/>
            { this.state.filler ? <View style={styles.filler}/> : null }
          </ScrollView>
        )
        
        styles.filler = {
            height: 'Keyboard Height'
        }
        

        注意:这可能仅在您的 &lt;TextInput/&gt; 位于屏幕底部时才有效,就我而言。

        【讨论】:

        • 使用 es6 中的箭头函数来避免绑定方法 stackoverflow.com/questions/32192682/… 并且您还可以通过在 iOS 上实现 `keyboardWillShow' 来改进它。 (未在 Android 上实现)
        • 很好的建议。我注意到出现在键盘上方的 TextInput 的响应框架有点落后。谢谢!
        【解决方案7】:
        import {KeyboardAvoidingView} from 'react-native';
        
        <KeyboardAvoidingView style={styles.container} behavior="padding" enabled>
        
            <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
            <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
            <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
            <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
            <Text style={{height: 100, marginTop: 30}}> test text before input</Text>
        
            <TextInput
                style={{height: 40, borderColor: 'gray', borderWidth: 1}}
                onChangeText={(text) => this.setState({text})}
                value={this.state.text}
            />
        
            <Text style={{height: 100, marginTop: 20}}>1 test text after input</Text>
            <Text style={{height: 100, marginTop: 20}}>2 test text after input</Text>
            <Text style={{height: 100, marginTop: 20}}>3 test text after input</Text>
            <Text style={{height: 100, marginTop: 20}}>4 test text after input</Text>
            <Text style={{height: 100, marginTop: 20}}>5 test text after input</Text>
        
        </KeyboardAvoidingView>
        

        吃零食: https://snack.expo.io/H1BE5ZoXV

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-20
          • 2018-11-30
          • 2020-09-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-12
          • 1970-01-01
          相关资源
          最近更新 更多