react-navigation3.0版本的使用詳解

入門:

React Navigation誕生于React Native社區需要一個由javascript編寫的擴展且易于使用的導航解決方案。目前react-navigation已經更新到3.x版本了。如果對react-navigation不了解的可以先看React Native Express(http://www.reactnativeexpress.com/)前4章

什么是導航器:

導航器可以看作是一個普通的React組件,可以通過導航器來定義APP的導航結構,導航器還可以渲染通用元素,比如配置標題欄和選項卡欄,在React-navigation中有一下三種類型的導航器:createStackNavigator,createSwitchNavigator,createDrawerNavigator,createBottomTabNavigator,createMaterialBottomTabNavigator,createMaterialTopTabNavigator等,詳情請看官網:https://reactnavigation.org/docs/en/material-top-tab-navigator.html

兩個與導航器相關的概念:

  • navigation prop(屏幕導航屬性):通過navigation可以完成屏幕之間的調度操作
  • navigationOptions(屏幕導航選項):通過navigationOptions可以定制導航器顯示屏幕的方式(頭部標題,選項卡標簽等)

Navigation prop 詳解

當導航器中的屏幕被打開時,會收到一個navigation prop,navigation包含以下功能

  • navigate - 轉跳到其他界面
class ProfileScreen extends React.Component {
  render() {
    return (
      <Button
        onPress={()=>navigation('Profile', {name: '稻城'})}
        title="Set title name to '稻城'"
      />
    );
  }
}
  • goback - 關閉當前界面
class ProfileScreen extends React.Component {
  render() {
    return (
      <Button
        onPress={goBack()}
        title="Set title name to '稻城'"
      />
    );
  }
}
  • addListener - 訂閱導航生命周期的更新
  • isFocused - 一個函數返回true或false,查詢屏幕是否獲取焦點
  • state - 屏幕當前的state
class ProfileScreen extends React.Component {
  render() {
    const params = this.props.navigation.state
    return <Text>Name: {params.name}</Text>;
  }
}

  • setParams - 改變路由的params
class ProfileScreen extends React.Component {
  render() {
    return (
      <Button
        onPress={() => this.props.navigation.setParams({ name: 'Lucy' })}
        title="Set title name to '稻城'"
      />
    );
  }
}
  • dispatch - 向路由發送一個action
import { NavigationActions } from 'react-navigation';

const navigateAction = NavigationActions.navigate({
  routeName: 'Profile',
  params: {},

  // navigate can have a nested navigate action that will be run inside the child router
  action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }),
});
this.props.navigation.dispatch(navigateAction); 
  • dangerouslyGetParent - 返回父導航器的函數

navigation有一下幾種方式:

  • push - 將新路由推入堆棧
navigation.push(routeName, params, action)
  • pop - 回到堆棧中
navigation.pop(n)  //n為在路由堆棧中的第幾個screen
  • popToTop - 轉到堆棧頂部
navigation.popToTop()
  • replace - 用新的路由替換當前路由
navigation.replace(routeName, params, action)
  • reset - 刪除所有的navigation state并且使用這個reset的代替
navigation.reset([NavigationActions.navigate({ routeName: 'Profile' })], 0
  • dismiss - 關閉當前堆棧
navigation.dismiss()

createStackNavigator的使用

為APP提供一種在屏幕之間轉換的方式,其中每個新屏幕都放置在堆棧頂部。默認情況下,堆棧導航器配置為具有熟悉的iOS和Android外觀:新的屏幕從iOS右側滑入,從Android底部淡入。在iOS上,堆棧導航器也可以配置為模式樣式,屏幕從底部滑入。

API的定義

createStackNavigator(RouteConfigs, StackNavigatorConfig);

RouteConfigs

route configs對象是從路由名稱到路由配置的映射,它告訴導航器為該路由提供什么。

createStackNavigator({
  // For each screen that you can navigate to, create a new entry like this:
  Profile: {
    // `ProfileScreen` is a React component that will be the main content of the screen.
    screen: ProfileScreen,
    // When `ProfileScreen` is loaded by the StackNavigator, it will be given a `navigation` prop.

    // Optional: When deep linking or using react-navigation in a web app, this path is used:
    path: 'people/:name',
    // The action and route params are extracted from the path.

    // Optional: Override the `navigationOptions` for the screen
    navigationOptions: ({ navigation }) => ({
      title: `${navigation.state.params.name}'s Profile'`,
    }),
  },

  ...MyOtherRoutes,
});
StackNavigatorConfig

路由器的選項

  • initialRouteName - 設置堆棧的默認屏幕。必須匹配路由配置中的一個鍵
  • initialRouteParams - 初始路線的參數
  • initialRouteKey - 初始路由的可選標識符
  • defaultNavigationOptions - 用于屏幕的默認導航選項
  • paths - 路徑配置中設置的路徑的覆蓋映射

視覺選項

  • mode - 定義渲染和過渡的樣式:
    • card - 使用標準的iOS和Android屏幕過渡。這是默認值。
    • modal - 使屏幕從底部滑入,這是一種常見的iOS模式。僅適用于iOS,對Android沒有影響。
  • headerMode - 指定標頭的呈現方式:
    • float - 渲染單個標題,保持在頂部,并在屏幕更改時設置動畫。這是iOS上的常見模式。
    • screen - 每個屏幕都附有一個標題,標題與屏幕一起淡入淡出。這是Android上的常見模式。
    • none - 不會呈現標題。
  • headerBackTitleVisible- 提供了合理的默認值,以確定后退按鈕標題是否可見,但如果要覆蓋可以使用true或false在此選項中。
  • headerTransitionPreset- 指定headerMode: float啟用時標頭應如何從一個屏幕轉換到另一個屏幕。
    • fade-in-place - 標題組件交叉淡入淡出而不移動,類似于iOS的Twitter,Instagram和Facebook應用程序。這是默認值。
    • uikit - iOS的默認行為的近似值。
  • headerLayoutPreset - 指定如何布置標題組件。
    • left - 將標題錨定在左側,靠近后退按鈕或其他左側組件。這是Android上的默認設置。在iOS上使用時,隱藏標題后退標題。左側組件中的內容將溢出標題下方,如果您需要調整此內容,則可以使用headerLeftContainerStyle和headerTitleContainerStyle。此外,此對齊與此不兼容headerTransitionPreset: 'uikit'。
    • center - 將標題居中,這是iOS上的默認設置。
  • cardStyle - 使用此prop可以覆蓋或擴展堆棧中單個卡的默認樣式。
  • cardShadowEnabled - 使用此道具在過渡期間顯示可見陰影。默認為true
    cardOverlayEnabled - 使用此prop可在轉換期間顯示可見的堆棧卡覆蓋。默認為false。
  • transitionConfig- 返回與默認屏幕轉換合并的對象的函數(在類型定義中查看TransitionConfig )。提供的函數將傳遞以下參數:
    • transitionProps - 為新屏幕過渡道具。
    • prevTransitionProps - 轉換舊屏幕的道具。
    • isModal - 布爾值,指定屏幕是否為模態。
  • onTransitionStart - 卡轉換動畫即將開始時要調用的函數。
  • onTransitionEnd - 卡過渡動畫完成后要調用的函數。
  • transparentCard- 實驗 - 支持將堆棧中的所有卡片保持可見并添加透明背景而不是白色背景。這對于實現模式對話框很有用,其中前一個場景仍應在當前場景下可見。
navigationOptions 用于導航器內的屏幕導航選項
  • title - 可用作后備的字符串headerTitle。此外,將用作tabBarLabel(如果嵌套在TabNavigator中)或drawerLabel(如果嵌套在DrawerNavigator中)的后備。
  • header - React Element或給定HeaderProps返回React元素的函數,顯示為標題。設置為null隱藏標題。
  • headerTitle - 標題使用的字符串,反應元素或反應組件。默認為場景title。當使用的成分,它接收allowFontScaling,style和children道具。傳遞標題字符串children。
  • headerBackImage - React Element或Component在標題的后退按鈕中顯示自定義圖像。使用組件時,它在渲染(tintColor,title)時會收到許多道具。默認為帶有react-navigation/views/assets/back-icon.png后方圖像源的圖像組件,后者是平臺的默認后退圖標圖像(iOS上的V形符號和Android上的箭頭)。
  • headerRight - React Element顯示在標題的右側。
  • headerLeft - React元素或組件顯示在標題的左側。當使用的成分,它接收到一個數道具呈現時(onPress,title,titleStyle和更多-檢查Header.js完整的列表)。
  • headerStyle - 標題的樣式對象
  • .....還有好多就不一一列舉了,感興趣就去官網看看吧(https://reactnavigation.org/docs/en/stack-navigator.html)

createBottomTabNavigator的使用

屏幕底部的一個簡單標簽欄,可讓您在不同的路線之間切換。路由被懶惰地初始化 - 它們的屏幕組件在首次聚焦之前不會被安裝

API的定義

createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig);

RouteConfigs

route configs對象是從路由名稱到路由配置的映射,它告訴導航器為該路由提供什么,請參閱堆棧導航器中的示例。

BottomTabNavigatorConfig
  • initialRouteName - 首次加載時初始制表符路徑的routeName。
  • order - routeNames數組,用于定義選項卡的順序。
  • paths - 提供routeName到path config的映射,該映射覆蓋routeConfigs中設置的路徑。
  • backBehavior - 后退按鈕是否會導致選項卡切換到初始選項卡?如果是,則設置為initialRoute,否則none。默認為initialRoute行為。
  • tabBarComponent - 可選,覆蓋用作標簽欄的組件。
  • tabBarOptions - 具有以下屬性的對象:
    • activeTintColor - 活動選項卡的標簽和圖標顏色。
    • activeBackgroundColor - 活動選項卡的背景顏色。
    • inactiveTintColor - 非活動選項卡的標簽和圖標顏色。
    • inactiveBackgroundColor - 非活動選項卡的背景顏色。
    • showLabel - 是否為標簽顯示標簽,默認為true。
    • showIcon - 是否顯示選項卡的圖標,默認為true。
    • style - 標簽欄的樣式對象。
      -labelStyle - 選項卡標簽的樣式對象。
    • tabStyle - 選項卡的樣式對象。
      -allowFontScaling - 標簽字體是否應縮放以符合“文本大小”輔助功能設置,默認為true。
    • safeAreaInset- 覆蓋forceInset道具<SafeAreaView>。默認為{ bottom: 'always', top: 'never' }。可用鍵top | bottom | left | right隨值提供'always' | 'never'。
tabBarOptions: {
  activeTintColor: '#e91e63',
  labelStyle: {
    fontSize: 12,
  },
  style: {
    backgroundColor: 'blue',
  },
}
navigationOptions 用于導航器內的屏幕導航選項
  • title - 通用標題可以用作備用headerTitle和tabBarLabel。
  • tabBarVisible - true或false顯示或隱藏標簽欄,如果未設置則默認為true。
  • tabBarIcon - React Element或給定{ focused: boolean, horizontal: boolean, tintColor: string }返回React.Node 的函數,以顯示在選項卡欄中。horizontal是true當設備處于風景和false肖像時。每當設備方向改變時,都會重新呈現圖標。
  • tabBarLabel - 標簽欄或React元素中顯示的選項卡的標題字符串或給定的函數{ focused: boolean, tintColor: string }返回React.Node,以顯示在選項卡欄中。未定義時,使用場景title。要隱藏,請參閱tabBarOptions.showLabel上一節。
  • tabBarButtonComponent - 包含圖標,標簽和實現的React Component onPress。默認值是一個包裝器TouchableWithoutFeedback,使其行為與其他觸摸器相同。tabBarButtonComponent: TouchableOpacity會TouchableOpacity改用。
  • .....還有好多就不一一列舉了,感興趣就去官網看看吧(https://reactnavigation.org/docs/en/bottom-tab-navigator.html)

實戰部分

基于react-navigation3.0最新的版本實現stack in tabs 和stack over tabs 兩種效果

Stack in tabs

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import {
  createStackNavigator,
  createBottomTabNavigator,
  createAppContainer,
  createMaterialTopTabNavigator,
} from 'react-navigation'
import { HomeTab, FindTab } from './Router/routers'


const CreateTab = createMaterialTopTabNavigator({
  Home: {
    screen: HomeTab,
    navigationOptions: () => ({
      tabBarLabel: '首頁',
    })
  },
  Find: {
    screen: FindTab,
    navigationOptions: () => ({
      tabBarLabel: '發現',
    })
  }
}, {
  initialRouteName: 'Find',
  tabBarPosition: 'bottom',
  lazy: true,
  swipeEnabled: false,
  tabBarOptions: {
    activeTintColor: 'red',
    style: {
      backgroundColor: '#fff',
    },
  }
})

const CreaterTab = createAppContainer(CreateTab)

export default class App extends Component {
  render() {
    return (
      <CreaterTab />
    );
  }
}

Stack over tabs

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import {
  createStackNavigator,
  createBottomTabNavigator,
  createAppContainer,
  createMaterialTopTabNavigator,
} from 'react-navigation'
import { HomeTab, FindTab } from './Router/routers'
import WebScreen from './screen/web/webScreen'


const CreateTab = createMaterialTopTabNavigator({
  Home: {
    screen: HomeTab,
    navigationOptions: () => ({
      tabBarLabel: '首頁',
    })
  },
  Find: {
    screen: FindTab,
    navigationOptions: () => ({
      tabBarLabel: '發現',
    })
  }
}, {
  initialRouteName: 'Find',
  tabBarPosition: 'bottom',
  lazy: true,
  swipeEnabled: true,
  tabBarOptions: {
    activeTintColor: 'red',
    style: {
      backgroundColor: '#fff',
    },
  }
})

const StacksOverTabs = createStackNavigator({
  Root: {
    screen: CreateTab,
    navigationOptions: {
        header: () => null, 
    }
  },
  WebView: {
        screen: WebScreen,
        navigationOptions: {
            title: '熊孩寶測試',
        },
    }
});

const StacksOverTab = createAppContainer(StacksOverTabs)

export default class App extends Component {
  render() {
    return (
      <StacksOverTab />
    );
  }
}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • react-native.jpeg 本文是基于最新的react-navigation^2.9.1來書寫的。 如果遇...
    掛著鈴鐺的兔閱讀 221,110評論 131 299
  • react-navigation導航組件使用詳解 注意了,如果有小伙伴們發現運行作者提供的react-naviga...
    光強_上海閱讀 23,501評論 38 103
  • 本文是基于最新的react-navigation^2.9.1來書寫的。 要感謝掛著鈴鐺的兔看到一篇不錯的介紹,這里...
    HT_Jonson閱讀 901評論 0 52
  • 我已不記得這本書是從何時進入了我的書單,又從何時擺在了我的書架上,我讀的這版是2016年2月份的第6次印刷版,可見...
    完顏洋洋閱讀 300評論 0 0
  • 你從來就是小眾的,落得個清閑,浮生一把蒲扇,便散開了云遮霧繞; 你從來就是小眾的,落得個不羈,來世一壺濁酒,便迷幻...
    達馬Fumer閱讀 436評論 0 0