您的位置:首页 > Web前端 > React

React-Native解决键盘遮挡问题(Keyboard遮挡问题)

2017-02-28 09:57 579 查看
我在前面也写了一篇关于键盘遮挡问题的解决方案,这次的原理也差不多,不过在后续的研究中发现官方给了一个有意思的组件叫 KeyboardAvoidingView。然后就动手去试了一试,然而效果并不好!具体用法可以参考这里:点击打开链接

不过随着RN的更新,这个官网肯定会解决的,但是在官方还没填坑前,还是得自己动手解决啦。

我前面博客的处理方法:点击打开链接

其实原理是要获取到键盘的高度和输入框的位置,然后去计算偏移位置就可以了。

那么今天这篇是写什么呢?

我前面的方法主要是自己写了原生的代码,然后获取键盘宽高,但是我今天才知道,原来RN的Keyboard组件已经有这个了,所以可以把之前方法中的原生部分可以剪掉了,毕竟还是官方的靠谱呀~

然后,今天的第二个发现就是RN中获取一个组件在屏幕的位置,这个以前我不知道,是通过组件和父组件的位置,去计算组件在屏幕的位置,这个的麻烦就是层次越深,越不好计算,你要传的数据就太多了,导致计算繁琐,不好得到正确的位置。今天我就告诉大家一个好方法,也是RN自带的叫measure。每个view都有这个属性,它里面就有6个参数,分别为ox,oy,width,height,px,py。这里的px,py就是组件在屏幕的位置啦!真是太棒啦~~

于是,我根据这些新发现,写了一个组件,在需要用的TextInput组件下面直接使用,就可以啦!直接贴代码好了:

[javascript] view
plain copy

 





import React, { Component, PropTypes} from 'react';  

import {  

  StyleSheet, View, Keyboard, LayoutAnimation  

} from 'react-native';  

  

export default class InputBoard extends Component {  

  constructor(props) {  

    super(props);  

    this.state={  

      marginTop: 0,  

    };  

    this.keyboardShow = false;//当前键盘的状态,显示与否  

    this.baseLayout = null;  

    this.config = {  

      duration: 150,  

      create: {  

        type: LayoutAnimation.Types.easeOut,  

        property: LayoutAnimation.Properties.opacity,  

      },  

      update: {  

        type: LayoutAnimation.Types.easeInEaseOut,  

      }  

    };  

    this.basePos = null;  

  }  

  static propTypes = {  

    spaceHeight: PropTypes.number, //固定增加高度  

  }  

  static defaultProps = {  

    spaceHeight: 0,  

  }  

  componentWillMount() {  

    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));  

    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));  

  }  

  componentDidMount() {  

    if (this.root){  

      this.root.measure((ox, oy, width, height, px, py)=>{  

        this.basePos = {  

          ox: ox,  

          oy: oy,  

          width: width,  

          height: height,  

          px: px,  

          py: py  

        };  

        console.log(this.basePos);  

      });  

    }   

  }  

  componentWillUnmount() {  

    this.keyboardDidShowListener.remove();  

    this.keyboardDidHideListener.remove();  

  }  

  _keyboardDidShow(e) {//当键盘弹起来  

    this.keyboardShow = true;  

    // let moveY = -(e.startCoordinates.height-this.baseLayout.y-this.baseLayout.height-this.props.spaceHeight);  

    // if (moveY > 0){  

    //   console.log("did show", e, 'move y: ' + moveY);  

    //   LayoutAnimation.configureNext(this.config);  

    //   this.setState({  

    //     marginTop: moveY   

    //   });  

    // }  

  

    this.root.measure((ox, oy, width, height, px, py)=>{  

      if (this.basePos)  

      this.basePos = {  

        ox: ox,  

        oy: oy,  

        width: width,  

        height: height,  

        px: px,  

        py: py  

      };  

      let moveY = -(e.startCoordinates.height-this.basePos.py-this.props.spaceHeight);  

      if (moveY > 0){  

        console.log("did show", e, 'move y: ' + moveY);  

        LayoutAnimation.configureNext(this.config);  

        this.setState({  

          marginTop: moveY   

        });  

      }  

    });  

  }  

  _keyboardDidHide(e) {//当键盘收起后  

    this.keyboardShow = false;  

    if (this.state.marginTop != 0){  

      LayoutAnimation.configureNext(this.config);  

      console.log("did hide", e);  

      this.setState({  

        marginTop: 0,  

      });  

    }  

  }  

  onLayout(event){  

    // if (event.nativeEvent.target == ReactNative.findNodeHandle(this.root))  

    if (this.baseLayout == null){  

      this.baseLayout = event.nativeEvent.layout;  

    }  

  }  

  render() {  

    console.log('render board');  

    return (  

      <View ref={(r)=>{this.root = r}}   

        style={[styles.container, this.props.style, {marginTop: this.state.marginTop}]}  

        onLayout={this.onLayout.bind(this)} />  

    );  

  }  

}  

  

const styles = StyleSheet.create({  

    container:{  

    }  

});  

然后使用:

[html] view
plain copy

 





<TextInput style={styles.textInput} />  

<InputBoard spaceHeight={44}/>//textInput的高度是44.  

注意一点的是,我内部是使用的marginTop,所以在样式上有一定的要求,不能使用固定的位置,否则计算的位置有误差,甚至是不动。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: