[Android]React Nativationでキーボードと一緒にタブバーも上がってしまう問題の対策

2018年9月2日

 

ReactNativeで開発をする際ルーティングの為にReactNavigationを使っている方が多いかと思うのですが、

そのReactNavigationのタブバーを何も気にせず使っているとキーボードが出てきたときに(Android限定)タブバーも一緒に押し上げて残念な感じになってしまうというのがあったので、その解決方法を記しておきます。

 

KeyBoardのイベントを検知して、TabBarを非表示にする。

 

解決策としては、KeyBoardが表示されると同時にタブバーを非表示にしてやるだけです。

ただ、TabBarを直接非表示にしたりするAPIは提供されていないので、自前でTabBarをラップした形のコンポーネントを実装してその中で表示・非表示を切り替えます。

以下がWrapperComponentです。

import React from 'react'
import { Keyboard } from 'react-native'
import { TabBarBottom } from 'react-navigation'

class TabBarComponent extends React.PureComponent {

  constructor(props) {
    super(props)
    
     this.state = {
      isVisible: true
    }
    this.keyboardWillShow = this.keyboardWillShow.bind(this)
    this.keyboardWillHide = this.keyboardWillHide.bind(this)
  }

  componentWillMount() {
    this.keyboardEventLisetners = [ 
    Keyboard.addListener('keyboardDidShow', this.keyboardWillShow)
 Keyboard.addListener('keyboardDidHide', this.keyboardWillHide)
 ]
  }

  componentWillUnmount() {
    this.keyboardEventLisetners.forEach( listener => listener.remove())
  }

  keyboardWillShow = () => {
    this.setState({
      isVisible: false
    })
  }

  keyboardWillHide = () => {
    this.setState({
      isVisible: true
    })
  }

  render() {
    if( !this.state.isVisible ) {
      return 
    }
    return 
  }
}

export default TabBarComponent

 

これができたら、TabNavigatorの第二引数で自前のラッパーコンポーネントを指定して完了です。

import TabBarComponent from './TabBarComponent.js'

export default TabNavigator({
...
}, {
    initialRouteName: '...',
    tabBarComponent: TabBarComponent,
  })

iosではキーボードがタブバーを押し上げるという感じにはならないので、イベントの登録をAndroid限定にしてあげるとより硬い実装にはなるかと思いますが、そちらはお好みでという感じです。

 

まとめ

 

React Nativeはまだまだ発展途上で想定外の動きをしたりOSごとの動作の違いがあったりしてなかなかつらみがありますが、プロジェクトとして動的でなかなか面白いですね。

この記事の問題をネットで調べてみるとAndroidのmanifest.xmlを書き換えれば動くよみたいななのがあったのですが、タブバーのためにアプリ全体の設定を書き換えるのはいかがなものかということでこちらの対策をアップしました。

では。