react-native 路由與選單demo

jingxindeyi發表於2021-01-04

路由使用: react-native-router-flux
選單使用: react-native-side-menu


1. 效果

初始進入頁面
初始進入頁面
點選上方bar後
總覽

2. 元件

1. 選單元件

簡單定義了一個選單列表 列表中每一個item的點選都會重新重新整理整個介面 (使用父元件傳遞的方法)

import React, {Component} from 'react';
import { FlatList } from 'react-native-gesture-handler';
import {View, Text, TouchableHighlight, StyleSheet} from 'react-native';

const menuList = [
    {
        "id": "home",
        "name": "首頁",
        "routeKey": "fir"
    },
    {
        "id": "pwd",
        "name": "密碼管理",
        "routeKey": "pwd"
    },
    {
        "id": "notify_test",
        "name": "推送測試",
        "routeKey": "notify_test",
    }
];

/**
 *  <FlatList data={menuList} renderItem={this.renderOneMenu}
             keyExtractor = {item => item.id}/>
 */
class MyMenu extends Component {

    constructor(props) {
        super(props);
        this.renderOneMenu = this.renderOneMenu.bind(this); // 需要bind一下 不然函式內訪問this存在問題
    }

    render() {

        return (
            <View>
                <Text style={styles.head}>Menu</Text>
            <FlatList data={menuList} renderItem={this.renderOneMenu}
            keyExtractor = {item => item.id}/>
            </View>
        )
    }

    renderOneMenu({item}) {
        let _this = this;
        return (
            
            <View>
                <TouchableHighlight onPress = {() => _this.props.menuSelected(item)}>
                <Text style={styles.item}> {item.name} </Text>
                </TouchableHighlight>
            </View>
        )
    }
}

const styles = StyleSheet.create({
    head: {
        fontSize: 20,
        color: 'blue',
    },
    item: {
        fontSize: 16,
        fontWeight: '300',
        paddingTop: 10,
        left: 15
    }, 
})

export default MyMenu;

2. 主頁面元件

包含選單和路由
狀態中定了初始狀態的route

(部分元件程式碼未貼出 )


import React, {Component} from 'react';
import Fir from "./srcjs/na/ui/fir";
import Pwd from "./srcjs/na/ui/Pwd";
import MyMenu from './srcjs/na/menu';
import MyBar from './srcjs/na/mybar';
import NotifyTest from './srcjs/na/ui/noti_test';

import {
  Router,
  Stack,
  Scene,
  Actions,
} from 'react-native-router-flux';
import {StyleSheet} from 'react-native';
import SideMenu from 'react-native-side-menu';

class Main extends Component {

  constructor(props) {
    super(props);
    this.state = {
      menuOpen: false,
      routeKey: 'pwd',
    }
    this.openMenu = this.openMenu.bind(this);
    this.closeMenu = this.closeMenu.bind(this);
    this.menuSelected = this.menuSelected.bind(this);
    window.openMenu = this.openMenu;
    window.switchTo = this.switchTo;
    window.closeMenu = this.closeMenu;
  }

  switchTo(key) {
    Actions.push(key);
  }

  closeMenu() {
    this.setState({
      menuOpen: false,
    })
  }

  openMenu() {
    this.setState({
      menuOpen: true,
    })
  }

  menuSelected(item) {
    this.setState({
      menuOpen: false,
      routeKey: item.routeKey,
    });
  }

  render() {
    const menu = <MyMenu menuSelected={this.menuSelected} />;
    return (
      
      <SideMenu menu={menu} width={10} isOpen={this.state.menuOpen}>
      <Router>
        <Stack key="root">
          <Scene key="fir" initial={'fir' == this.state.routeKey} navBar={MyBar}  back={false} component={Fir} title="fir" titleStyle={styles.routeTitle}></Scene>
          <Scene key="pwd" initial={'pwd' == this.state.routeKey} navBar={MyBar}  back={false} component={Pwd} title="密碼" titleStyle={styles.routeTitle}></Scene>
          <Scene key="notify_test" initial={'notify_test' == this.state.routeKey} navBar={MyBar}  back={false} component={NotifyTest}></Scene>
        </Stack> 
      </Router>
      </SideMenu>
    
    )
  }
}

const styles = StyleSheet.create({
  routeTitle: {
    justifyContent: 'center',
    flex: 1,
    color: 'red',
  }
})

export default Main;

相關文章