React-native鍵盤遮擋輸入框問題的解決

來源:互聯網
上載者:User

標籤:

      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>

 

React-native鍵盤遮擋輸入框問題的解決

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.