React-native键盘遮挡输入框问题的解决

RN中要解决键盘遮挡输入框的问题其实有挺多方式,在这里只是记录其中的一些个人实际开发中使用到的。

方式一、使用scrollTo方法,这也是最简单最粗暴的,只是需要计算scrollview滚动的距离,并且处理一些体验的bug问题。大致思路是:组件render方法中使用scrollview,并且设置scrollview的keyboardShouldPersistTaps={true}(此步一定不能少,如果缺少该属性,接下来的一步将会不起作用),然后在scrollview中用一个view作为container包裹所有剩余的子视图,比如Text,TouchableHighlight之类的,并且用onStartShouldSetResponderCapture截取该view的事件,用以解决当点击页面上的按钮时,第一次点击只会收起键盘,第二次点击才会响应按钮方法的bug。然后在TextInput的onFocus方法中滚动scrollview,在onEndEditing中恢复scrollview的滚动。以下是在具体实现中的代码。

render方法的实现:

render:function() {

  return(
    <View style={styles.container}>
    <NavigationBar title={‘绑定手机号‘} onBackPress={this.onBackPress}/>
    <ScrollView ref=‘scroll‘ keyboardShouldPersistTaps={true} >
      <View style={styles.content} onStartShouldSetResponderCapture={(e) => {
        const target = e.nativeEvent.target;
        if (target !== React.findNodeHandle(this.refs.phoneInput) && target !== React.findNodeHandle(this.refs.codeInput)) {
          this.refs.phoneInput.blur();
          this.refs.codeInput.blur();
        }}}>

        <TextInput
          style = {styles.cardNumText}
          ref = ‘phoneInput‘
          onFocus={this.scrollViewTo.bind(this)}
          onEndEditing={()=>{this.refs.scroll.scrollTo(0)}}
          onChange = {this.cardNumberTextChanged.bind(this)}
          placeholder = ‘请输入预留手机号‘
          placeholderTextColor = ‘#481A5C‘
          keyboardType = ‘numeric‘
        />

        <View style = {styles.lineView}></View>

          <TouchableHighlight style = {styles.topButton} underlayColor=‘#9B9B9B‘ onPress = {this.jumpToNextPage.bind(this)}>
            <Text style = {styles.buttonText}>发送验证码</Text>
          </TouchableHighlight>
        <TextInput
          style = {styles.cardNumText}
          ref = ‘codeInput‘
          onFocus={this.scrollViewTo.bind(this)}
          onEndEditing={()=>{this.refs.scroll.scrollTo(0)}}
          placeholder = ‘输入验证码‘
          placeholderTextColor = ‘#999‘
          onChange = {this.cardNumberTextChanged}
          keyboardType = ‘number-pad‘
        />
        <View style = {styles.lineView}></View>

        <Text style = {styles.protectText}>
           XXXXXXXXXXXXXXXXXXX
        </Text>

        <TouchableHighlight style = {styles.downButton} underlayColor=‘#481A5C‘ onPress = {this.jumpToNextPage.bind(this)}>
          <Text style = {styles.buttonText}>下一步</Text>
        </TouchableHighlight>
      </View>
    </ScrollView>
  </View>);
}

  onFocus时调用的scrollViewTo方法的实现:

  scrollViewTo:function(e){
    let target = e.nativeEvent.target;
    let scrollLength = 100;
    if (target=== React.findNodeHandle(this.refs.codeInput)) {
      scrollLength = 160;
    }
    this.refs.scroll.scrollTo(scrollLength);
  },

  方式二、使用View包裹时,通过设置View的marginTop属性并且结合动画来实现:初始化一个state对象的值viewMarginTop用于设置Animated.View的marginTop,在textInput的onfocus时改变viewMarginTop的值,在onEndediting时恢复或者设置新的marginTop。具体为首先引入Animated,并且初始化state方法。(state内值的变化会触发界面上相关元素的再次熏染,具有reactivecocoa的相同的作用)

  getInitialState: function () {
    return {
      viewMarginTop: new Animated.Value(0),
    };
  },

在需要上升的视图中使用Animated.View,设置其mairginTop为viewMarginTop

<Animated.View style={{marginTop:this.state.viewMarginTop}}>

    //当然不建议将样式写在这里,这样会导致每次熏染都创建一次样式,你应该将样式定义到StyleSheet中

    //your Views and component

</Animated.View>

然后在onFucos的方法中用动画改变viewMarginTop的值,如下

  Animated.timing(
    this.state.viewMarginTop,
    {
      toValue: 160,
      duration: 250,
    }
  ).start();

要恢复只需要在onEndediting中用同样的原理恢复viewMarginTop的值即可.

方式三、通过监听scrollview上键盘的出现和消失,在出现和消失方法中设置某个state值的变化,来设置scrollview的contentInset,该方法只是在github上看过,具体本人并没有用过即:

1.在页面熏染完时添加监听

componentDidMount: function () {
  // Keyboard events监听
  DeviceEventEmitter.addListener(‘keyboardWillShow‘, this.updateKeyboardSpace)
  DeviceEventEmitter.addListener(‘keyboardWillHide‘, this.resetKeyboardSpace)
},

componentWillUnmount: function () {
  // TODO: figure out if removeAllListeners is the right thing to do
  DeviceEventEmitter.removeAllListeners(‘keyboardWillShow‘)
  DeviceEventEmitter.removeAllListeners(‘keyboardWillHide‘)
},

getInitialState: function (props) {//初始化变量
  this.viewIsInsideTabBar = false
  return {
    keyboardSpace: 0,
  }
},

// Keyboard actions
updateKeyboardSpace: function (frames) {
  const keyboardSpace =  frames.endCoordinates.height//获取键盘高度
  this.setState({
    keyboardSpace: keyboardSpace,
  })
},

resetKeyboardSpace: function () {
  this.setState({
    keyboardSpace: 0,
  })
},

//设置scrollview的contentInset

<ScrollView
  ref=‘keyboardView‘
  keyboardDismissMode=‘interactive‘
  contentInset={{bottom: this.state.keyboardSpace}}
  showsVerticalScrollIndicator={true}
</ScrollView>

时间: 2024-10-12 22:19:56

React-native键盘遮挡输入框问题的解决的相关文章

LinearLayout详解四:彻底解决软键盘遮挡输入框的问题

之前把预备知识都介绍完了,话说学以致用,接下来我们要通过重载LinearLayout类来解决软键盘覆盖的问题. 首先阐述一下这个问题,如下图所示: 然后看挡住输入框的情况 然后我们给出xml的源代码: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:lay

iOS键盘遮挡输入框,输入区域自动上移

在iOS开发过程当中,遇到关于键盘遮挡输入框的问题,经过网络参考与实践,总结如下: 登录窗口,上下放置两个UITextField,一个用户名,一个密码,放置的在屏幕下方1/3处,当点击用户名时,自动弹出键盘,正好挡住了输入框 解决思路: 1.BLoginViewController 实现UITextViewDelegate的方法 1 //实现了UITextFieldDelegate中的方法,当对TextField进行编辑即键盘弹出时,自动将输入框上移 2 -(BOOL)textFieldShou

iOS- UITextView与键盘回收与键盘遮挡输入框

一.UITextView 可以实现多行输入的文本框,基本属性与UITextField相似,可以输入多行,可以滚动.UITextView还有个代理方式- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 可以控制输入文字的数量,较为常用 #pragma mark UITextView的代理方法 //是否可以开始编辑 - (BOOL

react-native 键盘遮挡输入框

Android上已经自动对键盘遮挡输入框做了处理,所以我们只需要关注ios. 1.首先引入 KeyboardAvoidingView import { KeyboardAvoidingView } from 'react-native'; 2.然后在页面的最外层加上 KeyboardAvoidingView render(){ return <KeyboardAvoidingView behavior={'padding'} style={{flex: 1}}> {/*具体页面内容*/} &l

安卓H5软键盘遮挡输入框

<div class="label"> * <span><?php echo lang('receive_email_info'); ?></span> <input class="r-email" type="text" placeholder="<?php echo lang('please_in_receive_email'); ?>3333"> &

解决键盘遮挡输入框的问题

1)首先得遵守协议UITextFieldDelegate @interface userInfoViewController()<UITextFieldDelegate> 2)设置代理(下面的self都是输入框所在的父view) textField.delegate = self; 3)实现UITextFieldDelegate的三个方法即可: - (BOOL)textFieldShouldReturn:(UITextField *)textField {     [textField res

android 键盘遮挡 父布局上滚解决

private void controlKeyboardLayout(final View root, final View scrollToView) { root.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect rect = new Rect(); //获取root在窗体的可视区域 root

键盘遮挡输入框处理

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px "PingFang SC"; color: #008400 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #3e1e81 } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #000000 } span.s

react native配置环境watchman监控安装失败解决办法

1,安装出错提示在安装watchman之前先运行 brew link pcre; 2, 还是提升错误不能连接: 3,试试运行,还说不行: 4,给路径授予权限,输入权限密码,这个是重点:sudo chown -R $(whoami) /usr/local 5,再运行一次,连接成功了: 6,再brew install watchman,成功了!-