react-navigation圖文攻略

接觸react-native有一段時間了,感受學習最大的難點就是 rn的國內資料很少,老外寫的文檔看起來不舒服javascript

其中在react-navigation上面花了很長的時間,搞的心力憔悴,可是看國內的文章,不少都是2.x版本的,api不向下兼容,各類報錯對象不存在,前期每天踩坑html

後來看了很長時間的官方文檔,才搞清楚react-navigation的使用前端

因此在我感受我如今已經踩過不少坑的狀況下,我決定寫這篇文章,來幫助rn開發者儘量的跳過react-navigation的一些坑java

本人使用react-native的一些練習代碼githubreact

react-native官網android

react-navigation官網ios

本文章基於 "react-navigation": "^3.0.9" 假如版本跨度比較大,本文可能就不適合了git

另外,學習庫或者插件最好的方式就官方閱讀文檔(感受有點打臉本身)github

安裝

儘可能不要看百度出來的文章,,例如**dn,比較陳舊,已經不是個當前版本,必定要看文檔web

rn項目裏面,我推薦使用yarn, npm有時候會出現依賴不全的問題

在已經初始化完成,而且確保能夠運行的rn項目裏面,輸入一下命令

yarn add react-navigation
yarn add react-native-gesture-handler
react-native link react-native-gesture-handler
複製代碼

在已經搭建好的項目裏面,運行上面的命令,這都是必須的,詳情請看文檔React navigation安裝

安裝完成後啓動項目(啓動無報錯即意味着navigation安裝成功了)

導航器

沒有接觸過原生開發的web開發者看到這些很react風格的導航器名稱,必定很陌生,不要緊,後面圖示

rn上的導航器的編寫就是相似 前端的路由的編寫,經過rn的導航器來決定App的路由結構,以及個性化的頁面

  • createStackNavigator 最基本的頁面 自帶上方導航欄

    爲你的應用程序提供一種在每一個新屏幕放置在堆棧頂部的屏幕之間轉換的方法。

  • createBottomTabNavigator

    頁面底部的標籤欄,可以讓您在不一樣路由之間進行切換。 路由被懶加載 - 它們的屏幕組件只有在第一次獲取焦點時纔會被加載。

  • createMaterialBottomTabNavigator

    功能上和 createBottomTabNavigator 同樣,這個更加個性化,可是咱們能夠基於createBottomTabNavigator自定義任意底部導航欄

    屏幕底部的材料設計主題標籤欄,可以讓您在不一樣路由之間切換。 路由被懶加載 - 它們的屏幕組件直到第一次獲取焦點時才被加載。

  • createMaterialTopTabNavigator

    屏幕頂部左右滑動切換tab

    屏幕頂部的材料設計主題標籤欄, 可經過點擊路線或水平滑動來切換不一樣的路由。 默認狀況下, 轉換是動態的。 每一個路由的屏幕組件將當即安裝。

  • createDrawerNavigator: 抽屜效果導航器,由側邊劃出;

  • createSwitchNavigator:

    createSwitchNavigator 的用途是一次只顯示一個頁面。 默認狀況下,它不處理返回操做,並在你切換時將路由重置爲默認狀態。(特定場合纔會使用)

經常使用的導航器就這麼多,下面將一一介紹給你們

使用vscode開發一些必備的插件

工欲善其事,必先利其器,好的開發環境能夠有效地加速開發速度,以及開發體驗感

使用vscode開發,推薦安裝Full React/React Native/React Router/Redux/GraphQL/ES7/Testing/PropTypes snippets

另外開發react推薦插件

React Native Snippet

React Native Tools

Reactjs code snippets

以上插件安裝完成後,就基本知足使用vscode進行react native的開發了 :wink:

安裝好的項目咱們稍微改造一下,

one.js two.js three.js 是頁面 隨便寫點什麼就好

navigation文件夾內部進行導航器的管理

createStackNavigator

這個是最多見的一個導航器,大部分頁面都是經過他進行配置的,使用起來也很簡單

先看看官方說明

如今咱們在navigation/index.js進行路由的配置

import { createStackNavigator, createAppContainer } from 'react-navigation'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'

const Stack = createStackNavigator({
  One: {
    screen: One
  },
  Two: {
    screen: Two
  },
  Three: {
    screen: Three
  }
})

export default createAppContainer(Stack)
// createAppContainer是 react-navigation 的app容器,並將頂層的 navigator 連接到整個應用環境(後面再說)
複製代碼

如今咱們須要在根節點導出這個導航器配置,因此須要修改根目錄的App.js

import React, { Component } from 'react'
import Navigation from './app/navigation'

export default class App extends Component {
  render() {
    return <Navigation /> } } 複製代碼

這個咱們就導出導航器配置,接下來重啓項目

成功了!

可是目前還不能進行頁面以前的切換,react-navigation提供了導航器以前的切換功能

關於切換路由 react-navigation 提供了不少api,下圖是最基礎的一部分

還記得前面建立容器的API createAppContainer嗎

他在props裏面提供了navigation對象,用於進行導航器切換

在One.js裏面添加切導航器的代碼One.js

import React, { Component } from 'react'
import { Text, View, Button } from 'react-native'

export default class One extends Component {
  render() {
    return (
      <View> <Text> One </Text> <Button title="跳轉到Two頁面" onPress={() => { this.props.navigation.navigate('Two') }} /> </View> ) } } 複製代碼

原生的感受真的棒~

咱們不只能夠切換頁面,還能夠像原生同樣配置頁面,react-navigation提供了大量的導航的自定義配置

例如

咱們能夠添加頁面標題,ios與android,導航欄會自適應

咱們能夠任意的選擇顯示或者不顯示導航欄

設置導航欄顏色 等等你能夠想到的個性化設置

更新naviigation/index.js

import { createStackNavigator, createAppContainer } from 'react-navigation'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'

const Stack = createStackNavigator({
  One: {
    screen: One,
    navigationOptions: {
      title: 'One'
    }
  },
  Two: {
    screen: Two,
    navigationOptions: {
      title: 'Two',
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    }
  },
  Three: {
    screen: Three,
    navigationOptions: {
      title: 'Three'
    }
  }
},{

})

export default createAppContainer(Stack)
複製代碼

更多的navigationOptions的配置請看官方文檔的

配置標題欄

導航選項

導航器內部屏幕的選項

createBottomTabNavigator

大部分的移動端項目都有底部導航欄,得益於單頁應用,webapp更多的出如今原生端那麼在react-native上,如何建立一個底部導航欄呢?

從web的角度理解 就是 經過底部導航欄進行組件的懶加載切換

讓咱們根據官方文檔建立一個導航欄試試

修改navigation/index.js

import {
  createStackNavigator,
  createBottomTabNavigator,
  createAppContainer
} from 'react-navigation'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'
const BottomBar = createBottomTabNavigator(
  {
    One: {
      screen: One,
      navigationOptions: {
        title: 'One'
      }
    },
    Two: {
      screen: Two,
      navigationOptions: {
        title: 'Two'
      }
    },
    Three: {
      screen: Three,
      navigationOptions: {
        title: 'Three'
      }
    }
  },
  {
    initialRouteName: 'One' // 初始化頁面
  }
)
const Stack = createStackNavigator({
  BottomBar: {
    screen: BottomBar,
    navigationOptions: {
      header: null
    }
  }
})

export default createAppContainer(Stack)
複製代碼

咱們引入了createBottomTabNavigatorcreateBottomTabNavigator裏面加了3個頁面,最後將導出的底部導航器對象再加入到createStackNavigator中,做爲普通頁面的形式

基礎的底部導航器實現了~

在基礎API上面,咱們能夠作不少自定義的操做,自定義圖標自定義文字,等等,具體請看文檔

下面咱們給咱們的導航欄加一個圖標,讓他看起來更加美觀

在項目裏面添加幾個小icon(圖片用的是iconfont上面的)

網絡上9成的文章都說明了在rn項目裏面使用 react-native-vector-icons 這個圖標庫進行圖標的添加 我這裏使用不常見的方案,使用本地png圖片做爲底部icon,固然這個使用在具體項目裏面應該封裝起來,這樣類小程序的模式,我相信能夠很好的幫助理解,如下編碼方式僅供學習

修改navigation/index.js

import React from 'react'
import { Image } from 'react-native'
import {
  createStackNavigator,
  createBottomTabNavigator,
  createAppContainer
} from 'react-navigation'

import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'
const BottomBar = createBottomTabNavigator(
  {
    One: {
      screen: One,
      navigationOptions: {
        title: 'One',
        tabBarIcon: ({ tintColor }) => {
          let sourceImg
          if (tintColor == '#1296db') {
            sourceImg = require('../image/one-active.png')
          } else {
            sourceImg = require('../image/one.png')
          }
          return (
          <Image
            source={sourceImg}
            style={{ width: 24, height: 24 }}
            color={tintColor}
          />
        )}
      }
    },
    Two: {
      screen: Two,
      navigationOptions: {
        title: 'Two',
        tabBarIcon: ({ tintColor }) => {
          console.log(tintColor);
          let sourceImg
          if (tintColor == '#1296db') {
            sourceImg = require('../image/my-active.png')
          } else {
            sourceImg = require('../image/my.png')
          }
          return (
          <Image
            source={sourceImg}
            style={{ width: 24, height: 24 }}
            color={tintColor}
          />
        )}
      }
    },
    Three: {
      screen: Three,
      navigationOptions: {
        title: 'Three',
        tabBarIcon: ({ tintColor }) => {
          let sourceImg
          if (tintColor == '#1296db') {
            sourceImg = require('../image/message-active.png')
          } else {
            sourceImg = require('../image/message.png')
          }
          return (
          <Image
            source={sourceImg}
            style={{ width: 24, height: 24 }}
            color={tintColor}
          />
        )}
      }
    }
  },
  {
    initialRouteName: 'One', // 初始化頁面
    tabBarOptions: {
      activeTintColor: '#1296db',
      inactiveTintColor: 'black'
    }
  }
)
const Stack = createStackNavigator({
  BottomBar: {
    screen: BottomBar,
    navigationOptions: {
      header: null
    }
  }
})

export default createAppContainer(Stack)
複製代碼

reactnavigation的導航欄只能作這些嗎?固然不是,能夠經過指定tabBarComponent,來自定義你的導航欄組件,這個比較複雜,我後期會寫一篇文章出來詳細說明

createMaterialBottomTabNavigator

這個給人一種開箱即用的感受,至於項目當中具體選擇什麼,這個要看需求

文檔明確指出,須要安裝如下庫

yarn add react-navigation-material-bottom-tabs react-native-paper react-native-vector-icons
react-native link react-native-vector-icons
複製代碼

咱們來實現一下官方案例的效果

修改navigation/index.js

import React from 'react'
import {
  createStackNavigator,
  createAppContainer
} from 'react-navigation'
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs'
import Ionicons from 'react-native-vector-icons/Ionicons'
import One from '../pages/One'
import Two from '../pages/Two'
import Three from '../pages/Three'

const BottomMater = createMaterialBottomTabNavigator(
  {
    One: {
      screen: One,
      navigationOptions: {
        tabBarColor: '#3472EE', // 頁面背景色
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-home" color={tintColor} size={24} />
        )
      }
    },
    Two: {
      screen: Two,
      navigationOptions: {
        tabBarColor: '#EC3E3E',
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-options" color={tintColor} size={24} />
        )
      }
    },
    Three: {
      screen: Three,
      navigationOptions: {
        tabBarColor: '#0EA748',
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-chatbubbles" color={tintColor} size={24} />
        )
      }
    }
  },
  {
    initialRouteName: 'One',
    activeColor: 'white',
    inactiveColor: 'gray',
    shifting: true
  }
)

const Stack = createStackNavigator({
  BottomMater: {
    screen: BottomMater,
    navigationOptions: {
      header: null
    }
  }
})

export default createAppContainer(Stack)

複製代碼

這樣相似的效果,react-navitation均可以完成,發揮你的想象力🤣

關於底部導航器的配置不少,沒辦法經過一篇文章一一介紹,詳情請看官方文檔

createMaterialTopTabNavigator

屏幕頂部的標籤欄, 可經過點擊路線或水平滑動來切換不一樣的路由。 默認狀況下, 轉換是動態的。 每一個路由的屏幕組件將當即安裝。

能夠看一下我以前模擬拼多多的頁面(當時是作技術驗證)

就這樣的效果

下面咱們能夠根據文檔在咱們的demo項目裏面本身實現一下這樣的效果

新增兩個頁面 Four.js Five.js 隨便寫點什麼就行

爲了更加合理設置邏輯,我將TopBar的全部導航器配置代碼放到一個文件當中

navigation文件夾內新建文件TopBar.js

import { createMaterialTopTabNavigator } from 'react-navigation'
import One from '../pages/One'
import Four from '../pages/Four'
import Five from '../pages/Five'

export default createMaterialTopTabNavigator(
  {
    One: {
      screen: One, // 配置頁面
      navigationOptions: {
        tabBarLabel: 'One'
      }
    },
    Four: {
      screen: Four,
      navigationOptions: {
        tabBarLabel: 'Four'
      }
    },
    Five: {
      screen: Five,
      navigationOptions: {
        tabBarLabel: 'Five'
      }
    }
  },
  {
    initialRouteName: 'One',
    lazy: true,
    tabBarOptions: {
      scrollEnabled: true,
      upperCaseLabel: false, // 是否大寫
      activeTintColor: 'red', // 活動選項卡
      inactiveTintColor: 'red', // "非活動" 選項卡
      tabStyle: {
        // 選項卡樣式
        // width: 60,
        // paddingTop: 35,
        paddingBottom: 4
      },
      style: {
        backgroundColor: 'white' // 頭部導航欄樣式
      },
      indicatorStyle: {
        backgroundColor: 'red' // 指示器樣式
      }
    }
  }
)

複製代碼

最後修改navigation/index.js,將咱們新建的頂部導航器導入

import React from 'react'
import { Image } from 'react-native'
import {
  createStackNavigator,
  createBottomTabNavigator,
  createAppContainer
} from 'react-navigation'
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs'
import Ionicons from 'react-native-vector-icons/Ionicons'
import TopBar from './TopBar'
import Two from '../pages/Two'
import Three from '../pages/Three'

const BottomMater = createMaterialBottomTabNavigator(
  {
    TopBar: {
      screen: TopBar,
      navigationOptions: {
        tabBarColor: '#3472EE', // 頁面背景色
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-home" color={tintColor} size={24} />
        )
      }
    },
    Two: {
      screen: Two,
      navigationOptions: {
        tabBarColor: '#EC3E3E',
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-options" color={tintColor} size={24} />
        )
      }
    },
    Three: {
      screen: Three,
      navigationOptions: {
        tabBarColor: '#0EA748',
        tabBarIcon: ({ tintColor }) => (
          <Ionicons name="ios-chatbubbles" color={tintColor} size={24} />
        )
      }
    }
  },
  {
    initialRouteName: 'TopBar',
    activeColor: 'white',
    inactiveColor: 'gray',
    shifting: true
  }
)

const Stack = createStackNavigator({
  BottomMater: {
    screen: BottomMater,
    navigationOptions: {
      header: null
    }
  }
})

export default createAppContainer(Stack)

複製代碼

是否是很簡單,或者所,是否是學會了react-navigation的套路了 ~

到這裏多聯繫,多理解,基本能夠完成通常項目的搭建了,

你也能夠看看我寫過的其餘文章,或者一些react-native的倉庫代碼,

定位 消息推送 APP啓動屏 第三方集成 RN配置全面屏 都獲得了比較好的解決

RN相關文章

React-Native項目中使用Redux

React-Native使用極光進行消息推送

RN打包android APK文件

React Native樣式的另類寫法.md

React-Native 回到頂部.md

React-native可能遇到的問題

關於createDrawerNavigator(抽屜組件) 和 createSwitchNavigator(僅顯示一次頁面),放到後面再說~

相關文章
相關標籤/搜索