react-native-router-fluxを使ってRouter設計するとき、タブバーUI用にTabsコンポーネントがある。アプリのスクリーン下部にあるナビゲーションUIのことだ。
タブバーデザインにおいてよほどの理由がない限りは、Tabsコンポーネントを使う。UIコンポーネントを利用すれば同様のものが設置できるし、自作タブバーにすることもできるが、わざわざそうする理由もない。なにより遷移設定が面倒くさい。
そんなTabsコンポーネントであるが、アクティブ時のカラーや非アクティブ時のカラーをカスタマイズするpropsがある。これを書き加えることで、タップしたときに色を変えられるわけだ。
しかしアイコン表示において手こずった事案があった。
このエントリーでは、フォーカスされているタブのアイコンにアクティブカラーをつける方法を共有したい。
- react-native ^0.59.8
- react-native-router-flux ^4.0.6
- native-base ^2.13.4
タブバーにアイコンを表示する
まずはRouter設定をする。使うコンポーネントは、
- <Router>
- <Tabs>
- <Scene>
の3つ。タブは「ホーム、カート、設定」を切り替える単純なものを想定している。
export default function AppScreen () {
return (
<Router>
<Tabs
key='main'
swipeEnabled={ true }
animationEnabled={ false }
tabBarStyle={{backgroundColor:'#F8F8F8'}}
>
<Scene
key="homeScreen"
component={ HomeScreen }
title="ホーム"
tabBarLabel="ホーム"
navigationBarStyle={{backgroundColor:'#F8F8F8'}}
icon={() => <Icon active name="home" />} // 👈
/>
<Scene
key="cartScreen"
component={ CartScreen }
title="カート"
tabBarLabel="カート"
navigationBarStyle={{backgroundColor:'#F8F8F8'}}
icon={() => <Icon active name="ios-basket" />} // 👈
/>
<Scene
key="otherScreen"
component={ OtherScreen }
title="設定"
tabBarLabel="設定"
navigationBarStyle={{backgroundColor:'#F8F8F8'}}
icon={() => <Icon active name="settings" />} // 👈
/>
</Tabs>
</Router>
);
}
上記ソースコードのコメントアウト行を見てほしい。
各タブにアイコン設置するため、<Icon>
を使っている。これはNativeBaseのIconコンポーネントだ。<Scene>
にそれぞれ設定することでアイコンが表示される。以下のようになると思う。
つづいては、タブがフォーカスされたときにアクティブカラーを着色する工程だ。
タブがフォーカスされているとき(されていないとき)のカラーを指定する
タブをタップしてフォーカスされたときに、テキストおよびアイコンがアクティブであるとわかるようにカラーを変えたい。
export default function AppScreen () {
return (
<Router>
<Tabs
key='main'
swipeEnabled={ true }
animationEnabled={ false }
tabBarStyle={{backgroundColor:'#F8F8F8'}}
activeTintColor="#e17055" // 👈 アクティブのとき
inactiveTintColor="#a39f9d"// 👈 非アクティブのとき
>
...
</Tabs>
</Router>
);
}
上記ソースコードのコメントアウト行を見てほしい。
activeTintColor propsがアクティブ時のカラーコードで、inactiveTintColor propsが非アクティブ時のカラーコードを設定している。いずれのpropsも文字列を受け付ける。
現在フォーカスされているホームタブのテキストはアクティブカラーになっている。ところが、アイコンのカラーは変わっていない。それもそのはずで、外部のコンポーネントなのだから仕方がない。
<Icon>
は、NativeBaseのコンポーネントだった。アイコンのカラーを変更するには、style propsにオブジェクト形式で、CSSを記述すればよい。
export default function AppScreen () {
return (
<Router>
<Tabs
...
>
<Scene
key="homeScreen"
component={ HomeScreen }
title="ホーム"
tabBarLabel="ホーム"
navigationBarStyle={{backgroundColor:'#F8F8F8'}}
icon={({focused}) => <Icon active name="home" style={{color: focused ? '#e17055' : '#a39f9d'}} />} // 👈
/>
...
</Tabs>
</Router>
);
}
上記ソースコードのコメントアウト行を見てほしい。
<Scene>
のicon propsに設定した関数の引数から、focusedを受け取っている。これは真偽値が格納されている。つまりタブがフォーカスならtrueというわけだ。
style propsに、focusedがtrueならアクティブカラーで、falseなら非アクティブカラーがを渡している。これにてアイコンにもアクティブカラーを付与することができた。
まとめ
フォーカスされているタブのアイコンにアクティブカラーをつける方法の共有だった。
この内容では、NativeBaseのIconコンポーネントを使っているが、自作のsvgアイコンやほかのUIコンポーネントであっても同様のことができるはずだ。focusedを受け取ってフォーカスか否かを確認して切り替えればよいのだから。
このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。