1. 程式人生 > >【React Native 安卓開發】----側邊欄的實現DrawerLayoutAndroid以及第三方框架react-native-side-menu的使用【第六篇】

【React Native 安卓開發】----側邊欄的實現DrawerLayoutAndroid以及第三方框架react-native-side-menu的使用【第六篇】

前言

做過安卓原生開發的童鞋們應該都做過側邊欄這個東西,而且對於開源框架SlidingMenu和android官方側滑選單DrawerLayout應該都不陌生。
那麼今天也在這裡給大家介紹一下React-Native中的側滑選單DrawerLayoutAndroid和第三方框架react-native-side-menu。

DrawerLayoutAndroid

介紹

封裝了平臺DrawerLayout(僅限安卓平臺)的React元件。抽屜(通常用於導航切換)是通過renderNavigationView方法渲染的,並且DrawerLayoutAndroid的直接子檢視會成為主檢視(用於放置你的內容)。導航檢視一開始在螢幕上並不可見,不過可以從drawerPosition指定的視窗側面拖拽出來,並且抽屜的寬度可以使用drawerWidth屬性來指定。

屬性

drawerLockMode enum(‘unlocked’, ‘locked-closed’, ‘locked-open’)

設定抽屜的鎖定模式。有三種狀態:

  • unlocked (預設值),意味著此時抽屜可以響應開啟和關閉的手勢操作。
  • locked-closed,意味著此時抽屜將保持關閉,不可用手勢開啟。
  • locked-open,意味著此時抽屜將保持開啟,不可用手勢關閉。
    無論抽屜處於那種狀態,都仍然可以呼叫openDrawer/closeDrawer這兩個方法開啟和關閉。

    drawerPosition enum(DrawerConsts.DrawerPosition.Left, DrawerConsts.DrawerPosition.Right)

指定抽屜可以從螢幕的哪一邊滑入。

drawerWidth number

指定抽屜的寬度,也就是從螢幕邊緣拖進的檢視的寬度。

keyboardDismissMode enum(‘none’, “on-drag”)

指定在拖拽的過程中是否要隱藏軟鍵盤。

  • none (預設值),拖拽不會隱藏軟鍵盤。

  • on-drag 當拖拽開始的時候隱藏軟鍵盤。

onDrawerClose function

每當導航檢視(抽屜)被關閉之後呼叫此回撥函式。

onDrawerOpen function

每當導航檢視(抽屜)被開啟之後呼叫此回撥函式。

onDrawerSlide function

每當導航檢視(抽屜)產生互動的時候呼叫此回撥函式。

onDrawerStateChanged function

每當抽屜的狀態變化時呼叫此回撥函式。抽屜可以有3種狀態:

  • idle(空閒),表示現在導航條上沒有任何正在進行的互動。

  • dragging(拖拽中),表示使用者正在與導航條進行互動。

  • settling(停靠中),表示使用者剛剛結束與導航條的互動,導航條正在結束開啟或者關閉的動畫。

renderNavigationView function

此方法用於渲染一個可以從螢幕一邊拖入的導航檢視。

樣例

這裡寫圖片描述

class hello extends Component{
   render() {  
    var navigationView = (  
    <View style={{flex: 1, backgroundColor:'blue'}}>  
      <Text style={{margin: 10, fontSize:15, textAlign: 'left'}}>I'm in the Drawer!</Text>  
    </View>  
  );  
  return (  
    <DrawerLayoutAndroid  
      drawerWidth={200}  
      drawerPosition={DrawerLayoutAndroid.positions.Left}  
      renderNavigationView={() =>navigationView}>  
      <View style={{flex: 1, alignItems:'center'}}>  
        <Text style={{margin: 10, fontSize:15, textAlign: 'right'}}>Hello</Text>  
        <Text style={{margin: 10, fontSize:15, textAlign: 'right'}}>World!</Text>  
      </View>  
    </DrawerLayoutAndroid>  
   );  
  }  
}

進階

這裡寫圖片描述

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    Image,
    TouchableOpacity,
    ViewPagerAndroid,
    ScrollView,
    Navigator,
    View,
    ListView,
    Dimensions,
    WebView,
    ToastAndroid,
    DrawerLayoutAndroid,

    } from 'react-native';

const{width,height} = Dimensions.get('window')

class hello extends Component{
   render() {  
    var navigationView = (  
    <View style={{flex: 1, backgroundColor:'blue'}}>  
        <TouchableOpacity onPress={this.close}>
            <Text style={[styles.textStyle, styles.textSmall]}>點選關閉側邊欄</Text>
        </TouchableOpacity> 
    </View>  
    );  

    return (  
        <DrawerLayoutAndroid  
            ref={(drawer) => { this.drawer = drawer; }}
            drawerWidth={200} 
            onDrawerClose={this.handleDrawerClose}
            onDrawerOpen={this.handleDrawerOpen} 
            drawerPosition={DrawerLayoutAndroid.positions.Left}  
            renderNavigationView={() =>navigationView}>  
            <View style={[styles.textContainer,styles.drawerStyle]}>
                <Text style={[styles.textStyle, styles.textLarge]} /** 當一個元件需要使用多個style樣式時,需要用[]將樣式括起來 */ >抽屜</Text>
                <Text style={[styles.textStyle, styles.textLarge]}>高逼格 相當簡單!</Text>
                <Text style={[styles.textStyle, styles.textSmall]}>從左側拖出策劃選單</Text>

                <TouchableOpacity onPress={this.open}>
                    <Text style={[styles.textStyle, styles.textSmall]}>點選開啟側邊欄</Text>
                </TouchableOpacity>
            </View> 
        </DrawerLayoutAndroid>  
   );  
  } 

   handleDrawerOpen=()=> { 
    //使用ToastAndroid元件彈出一個原生的Toast
    ToastAndroid.show("open drawer", ToastAndroid.SHORT);
  } 

  handleDrawerClose=()=>{
    ToastAndroid.show("close drawer", ToastAndroid.SHORT);
  }

  open=()=>{
    this.drawer.openDrawer();
  }

  close=()=>{
    this.drawer.closeDrawer();
  }
}

const styles = StyleSheet.create({
  drawerStyle: {
    backgroundColor: '#6699FF'
  },
  textContainer: {
    flex: 1,
    alignItems: 'center',
    flexDirection: 'column',
    justifyContent: 'center',
  },
  textStyle: {
    margin: 10,  
    color: 'white',
    textAlign: 'center'
  },
  textSmall: {
    fontSize: 15,
  },
  textLarge: {
    fontSize: 35,
  }
})

AppRegistry.registerComponent('hello', () => hello);

react-native-side-menu框架的使用

第一步

npm install react-native-side-menu --save

安裝好後再package.json中可以看到如下配置:
這裡寫圖片描述

第二步

引入:

import SideMenu from 'react-native-side-menu';

第三步

使用:

import SideMenu from 'react-native-side-menu';

class ContentView extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+Control+Z for dev menu
        </Text>
      </View>
    );
  }
}

class Application extends React.Component {
  render() {
    const menu = <Menu navigator={navigator}/>;

    return (
      <SideMenu menu={menu}>
        <ContentView/>
      </SideMenu>
    );
  }
}

第四步 樣例展示

這裡寫圖片描述

程式碼:
首頁程式碼

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    Image,
    TouchableOpacity,
    ViewPagerAndroid,
    ScrollView,
    Navigator,
    View,
    ListView,
    Dimensions,
    WebView,
    ToastAndroid,
    Button,
    DrawerLayoutAndroid,

    } from 'react-native';

import SideMenu from 'react-native-side-menu';
import Menu from './Menu.js'; //匯入選單元件

const uri_image_menu = 'http://image18-c.poco.cn/mypoco/myphoto/20160605/09/17351665220160605093956066.png';

const{width,height} = Dimensions.get('window')

class hello extends Component{
   constructor(props) {
     super(props);
     this.state = {
      isOpen : false,
      selectedItem:'About',
     };
   }

   toggle(){
      ToastAndroid.show('toggle', ToastAndroid.SHORT);
      this.setState({
        isOpen: !this.state.isOpen,
      });
   }

   updateMenuState(isOpen){
      this.setState({isOpen : isOpen
      });
   }

   onMenuItemSelected = (item) =>{
      this.setState({
        isOpen :false,
        selectedItem:item,
      });
   }

   render(){
    const menu = <Menu onItemSelected = {this.onMenuItemSelected}/>

    return(
      <SideMenu
        menu={menu}
        isOpen = {this.state.isOpen}
        onChange={(isOpen) => this.updateMenuState(isOpen)}
        >
        <View style={styles.container}>
            <Text style={styles.welcome}>
                  Welcome to React Native!
            </Text>
            <Text style={[styles.instructions, { color: 'red' }]}>
                        當前選中的選單是: {this.state.selectedItem}
            </Text>
          </View>

          <Button style={styles.button} onPress={() => this.toggle() } title="我是button,點選開啟側邊欄" >
              <Image
              source={{ uri: uri_image_menu, width: 32, height: 32, }} />
          </Button>

      </SideMenu>
    );
   }
}

const styles = StyleSheet.create({

    button: {
        position: 'absolute',
        top: 20,
        padding: 10,
    },
    caption: {
        fontSize: 20,
        fontWeight: 'bold',
        alignItems: 'center',
    },
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },
});

AppRegistry.registerComponent('hello', () => hello);

側邊欄程式碼:

import React,{Component} from 'react';
import {
    AppRegistry,
    StyleSheet,
    Dimensions,
    ScrollView,
    Text,
    Image,
    View,
} from 'react-native'

const window = Dimensions.get('window');
const uri = 'http://image18-c.poco.cn/mypoco/myphoto/20160605/09/1735166522016060509185507.png';

export default class Menu extends Component{
    static propTypes = {
        onItemSelected: React.PropTypes.func.isRequired,
    };// 注意這裡有分號

    render(){
        return(
            <ScrollView scrollsToTop={false} style={styles.menu}>
                <View style={styles.avatarContainer}>
                  <Image
                    style={styles.avatar}
                    source={{ uri:uri }}/>
                  <Text style={styles.name}>相濡以沫</Text>
                </View>

                <Text
                  onPress={() => this.props.onItemSelected('啦啦啦') }
                  style={styles.item}>
                  啦啦啦
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('點點我')}
                  style={styles.item}>
                  點點我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('抱抱我')}
                  style={styles.item}>
                  抱抱我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('親親我')}
                  style={styles.item}>
                  親親我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('啃啃我')}
                  style={styles.item}>
                  啃啃我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('拽拽我')}
                  style={styles.item}>
                  拽拽我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('閃閃我')}
                  style={styles.item}>
                  閃閃我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('照照我')}
                  style={styles.item}>
                  照照我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('戳戳我')}
                  style={styles.item}>
                  戳戳我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('贊讚我')}
                  style={styles.item}>
                  贊讚我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('誇誇我')}
                  style={styles.item}>
                  誇誇我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('看看我')}
                  style={styles.item}>
                  看看我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('卡卡我')}
                  style={styles.item}>
                  卡卡我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('呼呼我')}
                  style={styles.item}>
                  呼呼我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('點點我')}
                  style={styles.item}>
                  點點我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('抱抱我')}
                  style={styles.item}>
                  抱抱我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('親親我')}
                  style={styles.item}>
                  親親我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('啃啃我')}
                  style={styles.item}>
                  啃啃我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('拽拽我')}
                  style={styles.item}>
                  拽拽我
                </Text>

                <Text
                  onPress={() => this.props.onItemSelected('閃閃我')}
                  style={styles.item}>
                  閃閃我
                </Text>
      </ScrollView>
        );
    }
}

const styles = StyleSheet.create({
  menu: {
    flex: 1,
    width: window.width,
    height: window.height,
    backgroundColor: 'gray',
    padding: 20,
  },
  avatarContainer: {
    marginBottom: 20,
    marginTop: 20,
  },
  avatar: {
    width: 48,
    height: 48,
    borderRadius: 24,
    flex: 1,
  },
  name: {
    position: 'absolute',
    left: 70,
    top: 20,
  },
  item: {
    fontSize: 16,
    fontWeight: '300',
    paddingTop: 10,
  },
});

掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~
掃碼關注公眾號“偉大程式猿的誕生“,更多幹貨等著你~