みなさんこんにちは個別指導塾コミット塾長、AWESOME開発担当の船津です
今回はタブについて勉強してみました。
前回分はこちらreact-nativeでiOSアプリ開発 第13回 realmをreact-nativeで扱う(3)
目次
今回作りたい機能
- Todoリストの完了、未完了をタブで切り替える
- タブはスワイプで動かしたい
今回参考にしたサイト
今後もいろんなライブラリを使っていきますが、基本的にスターの多いものを選んでいきます。そのほうが資料が多いので…
タブバー
入れるだけでスワイプとかアニメーションに対応してくれるすごいやつです
https://github.com/skv-headless/react-native-scrollable-tab-view
fontawesome
みんな大好きFontAwesomeです
http://fontawesome.io/
アイコン
https://github.com/oblador/react-native-vector-icons
実践
まずインストール
npm install react-native-vector-icons --save
npm install react-native-scrollable-tab-view --save
フォントを手動でプロジェクトにコピー
ここを参考にどうぞ、プロジェクトをxcodeで開いてからフォントのttf
ファイルをコピペするだけでOKでした
コードを見るぞ
index.ios.js
import React, { Component } from 'react'; import { AppRegistry, } from 'react-native' import App from './app/containers/app' AppRegistry.registerComponent('realmPlayground', () => App);
containers/app.js
- スクロールビューを設置します
- customTabBarにpropsとして、タブの名前を渡します。
- RealmTodo(前回作ったアプリ)にpropsとしてvisibilityを渡します。
の部分はただの
Hello,World!
にしてもOKです- initialPageで最初に表示するページを指定します
import React, { Component } from 'react' import { AppRegistry, StyleSheet, Text, View, TextInput, TouchableHighlight, Switch, RefreshControl, ScrollView, } from 'react-native' import RealmTodo from '../components/realmTodo' import { ListView } from 'realm/react-native' import ScrollableTabView, { DefaultTabBar, } from 'react-native-scrollable-tab-view' import CustomTabbar from '../components/customTabBar' export default class App extends Component { render() { return ( <ScrollableTabView style={{marginTop: 20, }} tabBarPosition='bottom' initialPage={0} renderTabBar={() => <CustomTabbar tabList={['Active', 'Completed', 'All']}/>} > <RealmTodo tabLabel={'navicon'} visibility={'show_active'} /> <RealmTodo tabLabel='check-square-o' visibility={'show_completed'} /> <RealmTodo tabLabel="list-alt" visibility={'show_all'} /> </ScrollableTabView> ) } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, input: { flex: 1, justifyContent: 'center', alignItems: 'center', }, list: { flex: 4, justifyContent: 'center', }, completed: { textDecorationLine: 'line-through', textDecorationStyle: 'solid', }, });
components/customTabBar.js
- タブに対してアイコンを定義します
- propsとして渡されたtabListはこちらで順番にタブに表示されます
import React, { Component } from 'react' import { StyleSheet, Text, View, TouchableOpacity, } from 'react-native'; import Icon from 'react-native-vector-icons/FontAwesome' const myIcon = (<Icon name="rocket" size={30} color="#900" />) export default class CustomTabBar extends Component { tabIcons = [] propTypes:{ goToPage: React.PropTypes.func, activeTab: React.PropTypes.number, tabs: React.PropTypes.array, } render() { return <View style={[styles.tabs, this.props.style, ]}> {this.props.tabs.map((tab, i) => { return <TouchableOpacity key={tab} onPress={() => this.props.goToPage(i)} style={styles.tab}> <Icon name={tab} size={30} color={this.props.activeTab === i ? 'rgb(59,89,152)' : 'rgb(204,204,204)'} ref={(icon) => { this.tabIcons[i] = icon; }} /> <Text style={this.props.activeTab === i ? styles.tabTextActive : styles.tabTextNotActive}>{this.props.tabList[i]}</Text> </TouchableOpacity> })} </View> } } const styles = StyleSheet.create({ tab: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingBottom: 10, }, tabs: { height: 45, flexDirection: 'row', paddingTop: 5, borderWidth: 1, borderTopWidth: 0, borderLeftWidth: 0, borderRightWidth: 0, borderBottomColor: 'rgba(0,0,0,0.05)', }, tabTextNotActive: { fontSize: 12, color: '#B3B3B3' }, tabTextActive: { fontSize: 12, color: 'rgb(59,89,152)' }, })
出来上がり
こんな感じになります
最後に
CustomTabBarのところが難しかったです。
公式の真似をしただけなところがあるので、まだまだ勉強が必要ですね。
各タブに情報を渡すときにもっといい方法があるはず…
配列を渡してるのカッコ悪いですよね、そのうち直します