react-nativeでiOSアプリ開発 第15回 react-native drawerもscrollable-tab-viewもreact-native-router-fluxも使いたかった

全部使ってみようと思いました

みなさんこんにちは個別指導塾コミット塾長、AWESOME開発担当の船津です。

今回は
UI作成で大事な要素、タブ、ルーター、ドロワーと全部まとめて使ってみましょう。

今回のリポジトリ

react-native-scrollable-tab-viewに関しては前回の記事をご覧ください

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

react-nativeでiOSアプリ開発 第14回 scrollable-tab-viewと font-awesomeを使う

今回作ったもの

こんな感じで動作します

 

react-nativeでiOSアプリ開発 第15回 react-native drawerもscrollable-tab-viewもreact-native-router-fluxも使いたかった

よくあるアプリのページ移動ですね。

で、どんな構成か

Router

  • モバイルアプリはページをシーンという形で積み重ねて作ります
  • ページ間の移動はActions."KEYNAME"の形で記述します
  • componentはクラスを指定します
export default class App extends Component {
  render() {    
    return (      
    <Router>
      <Scene key="root">        
        <Scene key="start" component={TestDrawer} title="Start" text="page1" initial={true} onRight={() => Actions.todo()}  rightTitle="todo"/>
        <Scene key="todo" component={TodoWithTab} title="Todo" text="page2" hideNavBar={false} />        
        </Scene>
    </Router>
    )
  }
}

Drawer

  • contentにはクラスを指定します

class TestDrawer extends Component {
  openDrawer = () => {
    this._drawer.open()
  };
  closeDrawer = () => {
    this._drawer.close()
  };
  render() {
    return (
    <Drawer ref={(ref) => this._drawer = ref}
        content={<TestPanel closeDrawer={this.closeDrawer}/>}
        tapToClose={true}        
        >
        <View style={{flex: 1,justifyContent: 'center',}}>        
        <Text style={{textAlign: 'center',marginTop: 30,}}>{this.props.text}</Text>  
        <View style={{alignItems: 'center',}}>
          <TouchableHighlight style={styles.button} onPress={() => { this.openDrawer() }}
            activeOpacity={75 / 100}
            underlayColor={"rgba(47,56,78,1)"}>
            <Text>Open</Text>
          </TouchableHighlight>
        </View>        
      </View>
      </Drawer>
    )
  }
}

Drawer用コンポーネント

  • closeDrawerでDrawewerを閉じます
  • Actions.startで戻れるようにもなっています
class TestPanel extends Component {
  render(){
    const {closeDrawer} = this.props
    return (
      <View style={styles.container}>
        <Text style={styles.controlText}>Control Panel</Text>
        <Button onPress={Actions.todo}>
          Todo
        </Button>
        <Button onPress={closeDrawer}>
          go back to first page
        </Button>
        <Button onPress={Actions.start}>
          go back to first page(using router)
        </Button>
      </View>
    )
  }
} 

出来上がったコード


import React, { Component } from 'react'
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  TouchableHighlight,
  TouchableOpacity,
} from 'react-native'

import RealmTodo from '../components/realmTodo'
import ScrollableTabView from 'react-native-scrollable-tab-view'
import CustomTabbar from '../components/customTabBar'
import {Actions, Scene, Router} from 'react-native-router-flux'
import Drawer from 'react-native-drawer';
import Button from 'react-native-button';

class TestDrawer extends Component {
  openDrawer = () => {
    this._drawer.open()
  };
  closeDrawer = () => {
    this._drawer.close()
  };
  render() {
    return (
    <Drawer ref={(ref) => this._drawer = ref}
        content={<TestPanel closeDrawer={this.closeDrawer}/>}
        tapToClose={true}        
        >
        <View style={{flex: 1,justifyContent: 'center',}}>        
        <Text style={{textAlign: 'center',marginTop: 30,}}>{this.props.text}</Text>  
        <View style={{alignItems: 'center',}}>
          <TouchableHighlight style={styles.button} onPress={() => { this.openDrawer() }}
            activeOpacity={75 / 100}
            underlayColor={"rgba(47,56,78,1)"}>
            <Text>Open</Text>
          </TouchableHighlight>
        </View>        
      </View>
      </Drawer>
    )
  }
}
class TestPanel extends Component {
  render(){
    const {closeDrawer} = this.props
    return (
      <View style={styles.container}>
        <Text style={styles.controlText}>Control Panel</Text>
        <Button onPress={Actions.todo}>
          Todo
        </Button>
        <Button onPress={closeDrawer}>
          go back to first page
        </Button>
      </View>
    )
  }
} 
class TodoWithTab extends Component {
  render() {
    return (      
      
      <ScrollableTabView style={{marginTop: 40, borderTopWidth: 2, }} 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>
      
    )
  }
}

export default class App extends Component {
  render() {    
    return (      
     <Router>
      <Scene key="root">        
        <Scene key="start" component={TestDrawer} title="Start" text="page1" initial={true} onRight={() => Actions.todo()}  rightTitle="todo"/>
        <Scene key="todo" component={TodoWithTab} title="Todo" text="page2" hideNavBar={false} />        
        </Scene>
    </Router>
    )
  }
}

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',
  },
  button: {
    width: 100,
   height: 30,
   padding: 10,
   backgroundColor: 'lightgray',
   alignItems: 'center',
   justifyContent: 'center',
   margin: 3
  },
  controlPanel: {
    flex: 1,
    backgroundColor:'transparent',
  },
  controlPanelText: {
    color:'white',
  },
});

動作解説(ややこしいですね)

  • drawerでTestPanelを呼び出しています
  • TestPanelではActions.todoを呼び出してシーン間を移動したり、’closeDrawer’でdrawerを閉じます
  • TodoWithTabの動作は前回の記事を参照してください

おわり

どうだったでしょうか?なかなか難しいので、とにかく作って動かしてみてくださいね。

Instagram Feed

Load More

Instagram

専務取締役

funatsukeisuke

WEBと教育を組み合わせて何かおもしろいことをやってやろうと画策しています。AWESOMEでは開発を担当、個別指導塾コミットでは塾長と2足の草鞋を履きながら日々勉強しています。

他の投稿を見る →