【react-native-paper】BottomNavigationを実装してみた


まずはじめに

react-native-paperが提供しているBottomNavigationはreact-navigationが提供しているBottomtabNavigationとかなり似ているのですが、ただアニメーションがついていたりちょっとリッチな感じになっています。
今回目指す実装はこういった実装です↓

react-native-paperの導入

過去導入手順をまとめた記事があるので参考にしてください
導入手順

公式ドキュメント通りBottomNavigationを実装してみる

ただ公式ドキュメント通りやるとMusicタブのアイコンがうんたらかんたらと言われるので、MUSICを消します。

App.js
import React from 'react';
import { Provider as PaperProvider } from 'react-native-paper';
import AppNavigator from './navigation/AppNavigator'

export default function App() {
  return (
    <PaperProvider>
      <AppNavigator />
    </PaperProvider>
  );
}
/navigation/AppNavigator.js
import * as React from 'react';
import { BottomNavigation, Text } from 'react-native-paper';

const AlbumsRoute = () => <Text>Albums</Text>;

const RecentsRoute = () => <Text>Recents</Text>;

export default class AppNavigator extends React.Component {
    state = {
        index: 0,
        routes: [
            { key: 'albums', title: 'Albums', icon: 'album' },
            { key: 'recents', title: 'Recents', icon: 'history' },
        ],
    };

    _handleIndexChange = index => this.setState({ index });

    _renderScene = BottomNavigation.SceneMap({
        albums: AlbumsRoute,
        recents: RecentsRoute,
    });

    render() {
        return (
            <BottomNavigation
                navigationState={this.state}
                onIndexChange={this._handleIndexChange}
                renderScene={this._renderScene}
            />
        );
    }
}

一旦タブでの動きは完成しました。

タブに色を指定してみる

タブに色を付与する場合は、state.routesの各画面にcolorタグを付与してあげます。

    state = {
        index: 0,
        routes: [
            { key: 'albums', title: 'Albums', icon: 'album', color: '#000000' },
            { key: 'recents', title: 'Recents', icon: 'history', color: '#009688' },
        ],
    };

確認してみる

あれ変わってない!!なんで変わってないんだろ・・・
と思ったら同じこと思っている人がいました。

callStack

どうやらshifting={true}が必要みたいです。追加していきます。

    render() {
        return (
            <BottomNavigation
                navigationState={this.state}
                onIndexChange={this._handleIndexChange}
                renderScene={this._renderScene}
                shifting={true}
            />
        );
    }

ついでにスタイル等も整えてみます。
修正したAppNavigator.jsは以下です。

/navigation/AppNavigator.js
import * as React from 'react';
import { View, StyleSheet } from 'react-native'
import { BottomNavigation, Text } from 'react-native-paper';

const AlbumsRoute = () =>
    <View style={styles.textStyle}>
        <Text >Albums</Text>
    </View>;

const RecentsRoute = () =>
    <View style={styles.textStyle}>
        <Text >Recents</Text>
    </View>;
export default class AppNavigator extends React.Component {
    state = {
        index: 0,
        routes: [
            { key: 'albums', title: 'Albums', icon: 'album', color: '#000000' },
            { key: 'recents', title: 'Recents', icon: 'history', color: '#009688' },
        ],
    };

    _handleIndexChange = index => this.setState({ index });

    _renderScene = BottomNavigation.SceneMap({
        albums: AlbumsRoute,
        recents: RecentsRoute,
    });

    render() {
        return (
            <BottomNavigation
                navigationState={this.state}
                onIndexChange={this._handleIndexChange}
                renderScene={this._renderScene}
                labeled={true}
                shifting={true}
            />
        );
    }
}

const styles = StyleSheet.create({
    textStyle: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
    },
})


最後に

stackcallの記事を見つけるまでに時間かかってしまったので、投稿しました。
個人的にこのアニメーションのタブは好きなのでこれから多様して何か作っていきます。
記事良かったら共有などお願いします!