React Native 聊天室置底输入框的设计

来源:互联网 发布:mac 抹除系统 重装 编辑:程序博客网 时间:2024/06/04 17:41

哎,我又绕回了最初的设计方式

先讲讲之前的设计思路,通过监听键盘的事件,为了接近完美的效果,我监听的是keyboardWillShow、keyboardWillHide
通过打印监听的返回信息,我成功的获得了键盘弹起、收起的动画参数,这个很重要,我可以将这个动画参数,完全提供给输入框,这样她们就可以同步移动,人不知鬼不觉,媲美原生效果,事实上我也是这么做的,代码如下

componentDidMount () {    /** 注册键盘弹起事件监听  */    this.keyboardWillShowListener = Keyboard.addListener('keyboardWillShow', this._keyboardWillShow.bind(this))    this.keyboardWillHideListener = Keyboard.addListener('keyboardWillHide', this._keyboardWillHide.bind(this))}componentWillUnmount () {  /** 移除键盘监听 **/  this.keyboardWillShowListener.remove()  this.keyboardWillHideListener.remove()}

通过监听键盘行为触发动画

/** 键盘弹起 */_keyboardWillShow (e) {  if (!this.state.keyboardHeight) this.setState({ keyboardHeight: e.endCoordinates.height })  Animated.timing(this.state.compositeAnim, {    toValue: 1,    easing: Easing.keyboard,    duration: 250  }).start()}/** 键盘收起 */_keyboardWillHide (e) {  console.log(e)  Animated.timing(this.state.compositeAnim, {    toValue: 0,    easing: Easing.keyboard,    duration: 250  }).start()}
<Animated.View style={{ flex: 1, transform: [{   translateY: this.state.compositeAnim.interpolate({     inputRange: [0, 1],     outputRange: [0, -keyboardHeight]   }) }]}}> <ScrollView   ref='scrollView'   style={{ marginBottom: px2dp(112) }}   automaticallyAdjustContentInsets={false}   onContentSizeChange={(contentWidth, contentHeight) => {     if (this.flexViewHeight && contentHeight > this.flexViewHeight - px2dp(112)) {       undefined !== this.refs.scrollView && this.refs.scrollView.scrollToEnd()     }   }} >   { undefined !== messageList && messageList.length > 0 && messageList.map((item, index) => this.renderItem(item, index)) } </ScrollView> <View style={{ padding: px2dp(50),   paddingTop: px2dp(16),   paddingBottom: px2dp(16),   position: 'absolute',   bottom: 0,   left: 0,   right: 0,   backgroundColor: Colors.C8 }}>   <TextInput style={{ height: px2dp(80), borderRadius: px2dp(10), backgroundColor: Colors.C8, fontSize: px2dp(26), color: Colors.C3, lineHeight: px2dp(36), padding: px2dp(20), borderWidth: 1, borderColor: Colors.C7 }} placeholder='我来说两句' placeholderTextColor={Colors.C5}     returnKeyType='send'     underlineColorAndroid='transparent'     onChangeText={(message) => this.setState({ message })}     value={message}     onSubmitEditing={() => { sendChatMessage({ receiver, message, type: '1' }); this.setState({ message: '' }) }}   /> </View></Animated.View>

一切都是那么完美,在IOS上,到了Android上,keyboardWillShow、keyboardWillHide,这两个时间根本监听不到,keyboardDidShow、keyboardDidHide如果监听这两个事件,效果就会大打折扣,这时候,看到了RN官网提供的这个组件

KeyboardAvoidingView

竟然不用监听、不用动画就可以实现效果

<KeyboardAvoidingView  behavior='position' contentContainerStyle={{ flex: 1 }} style={{ flex: 1 }}  keyboardVerticalOffset={px2dp(132)} >  <ScrollView    ref='scrollView'    style={{ }}    automaticallyAdjustContentInsets={false}    onContentSizeChange={(contentWidth, contentHeight) => {      if (this.flexViewHeight && contentHeight > this.flexViewHeight - px2dp(112)) {        undefined !== this.refs.scrollView && this.refs.scrollView.scrollToEnd()      }    }}  >    { undefined !== messageList && messageList.length > 0 && messageList.map((item, index) => this.renderItem(item, index)) }  </ScrollView>  <View style={{    padding: px2dp(50),    paddingTop: px2dp(16),    paddingBottom: px2dp(16),    bottom: 0,    backgroundColor: Colors.C8  }}>    <TextInput style={{ height: px2dp(80), borderRadius: px2dp(10), backgroundColor: Colors.C8, fontSize: px2dp(26), color: Colors.C3, lineHeight: px2dp(36), padding: px2dp(20), borderWidth: 1, borderColor: Colors.C7 }} placeholder='我来说两句' placeholderTextColor={Colors.C5}      returnKeyType='send'      underlineColorAndroid='transparent'      onChangeText={(message) => this.setState({ message })}      value={message}      onSubmitEditing={() => { sendChatMessage({ chatId: navigation.state.params.chatId, receiver: null, message, type: '1' }); this.setState({ message: '' }) }}    />  </View></KeyboardAvoidingView>

UI上做了一点调整就可以达到了很好的效果
(其实内心是拒绝的,之前那种方案还可以练习一下动画)

原创粉丝点击