成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

react-navigation使用詳解

stonezhu / 1791人閱讀

摘要:導(dǎo)航組件使用詳解注意了,如果有小伙伴們發(fā)現(xiàn)運(yùn)行作者提供的示例項(xiàng)目報(bào)如下的錯(cuò)誤,可能是大家使用了命令導(dǎo)致的,解決這個(gè)錯(cuò)誤的辦法就是將刪除,然后重新使用命令來(lái)安裝,最后使用來(lái)起服務(wù),應(yīng)該就不報(bào)錯(cuò)了。

react-navigation導(dǎo)航組件使用詳解

注意了,如果有小伙伴們發(fā)現(xiàn)運(yùn)行作者提供的react-navigation示例項(xiàng)目報(bào)如下的錯(cuò)誤,可能是大家使用了 yarn install 命令導(dǎo)致的,解決這個(gè)錯(cuò)誤的辦法就是將nodemodules刪除,然后重新使用npm install 命令來(lái)安裝,最后使用 npm start 來(lái)起服務(wù),應(yīng)該就不報(bào)錯(cuò)了。如果還有報(bào)錯(cuò),請(qǐng)加作者交流群,將問(wèn)題反饋到群里,謝謝。

RN技術(shù)總結(jié)

作者React Native開(kāi)源項(xiàng)目OneM地址(按照企業(yè)開(kāi)發(fā)標(biāo)準(zhǔn)搭建框架完成開(kāi)發(fā)的):https://github.com/guangqiang-liu/OneM (歡迎小伙伴們 star)

作者簡(jiǎn)書(shū)主頁(yè):包含60多篇RN開(kāi)發(fā)相關(guān)的技術(shù)文章http://www.jianshu.com/u/023338566ca5 (歡迎小伙伴們:多多關(guān)注,多多點(diǎn)贊)

作者React Native QQ技術(shù)交流群:620792950 歡迎小伙伴進(jìn)群交流學(xué)習(xí)

友情提示:在開(kāi)發(fā)中有遇到RN相關(guān)的技術(shù)問(wèn)題,歡迎小伙伴加入交流群(620792950),在群里提問(wèn)、互相交流學(xué)習(xí)。交流群也定期更新最新的RN學(xué)習(xí)資料給大家,謝謝支持!

前言
react-navigation 組件是官方推薦使用的導(dǎo)航組件,功能和性能都遠(yuǎn)遠(yuǎn)的優(yōu)于之前的Navigator組件,公司的RN項(xiàng)目最早是使用的react-native-router-flux導(dǎo)航組件,因?yàn)槟莻€(gè)時(shí)候react-navigation 組件還沒(méi)有出來(lái),在使用了react-navigation后,感覺(jué)比react-native-router-flux組件有更加強(qiáng)大的功能,體驗(yàn)也略好些,這兩個(gè)導(dǎo)航組件是目前star最多的導(dǎo)航組件,并且他們都完美的支持與Redux框架的結(jié)合使用,推薦小伙伴們兩個(gè)組件都嘗試使用下。
react-navigation官方地址

react-navigation

react-navigation Demo地址

https://github.com/guangqiang-liu/react-navigation-demo

Demo示例講解包含三部分

react-navigation中最常用的基礎(chǔ)用法講解

react-navigation中StackNavigator與TabNavigator和DrawerNavigator的混合嵌套使用

react-navigation與Redux框架結(jié)合使用示例

Demo效果圖

注意: 有小伙伴說(shuō)Demo運(yùn)行報(bào)錯(cuò),這里大家需要注意,Demo clone下來(lái)之后,我們先要執(zhí)行 npm install 操作, 然后在執(zhí)行 react-native link,最后在 執(zhí)行 npm start 來(lái)運(yùn)行項(xiàng)目,如果還有其他的報(bào)錯(cuò)信息,歡迎進(jìn)群提出報(bào)錯(cuò)信息

對(duì)Redux用法不熟悉的同學(xué)們,請(qǐng)看作者的Redux入門講解

http://www.jianshu.com/p/faa98d8bd3fa

react-navigation 主要組成

react-navigation 組件主要由三大部分組成

StackNavigator:類似于iOS中的UINavigationController,頂部的導(dǎo)航欄,主要用于頁(yè)面間的跳轉(zhuǎn)

TabNavigator:類似于iOS中的UITabBarController,底部的tabBar選項(xiàng)卡,主要用于在同一tab下的不同頁(yè)面的切換

DrawerNavigator:類似于iOS中常用的抽屜功能,抽屜導(dǎo)航欄

下面我們對(duì)react-navigation詳解也主要圍繞這三個(gè)API來(lái)展開(kāi)

StackNavigator

StackNavigator導(dǎo)航欄的工作原理就和iOS中原生的UINavigationController一樣的,是以棧的方式來(lái)管理每一個(gè)頁(yè)面控制器的,當(dāng)使用push就是入棧,當(dāng)使用pop操作時(shí)就是出棧,這個(gè)很好理解,如果我們想讓一個(gè)頁(yè)面控制器有導(dǎo)航欄,那么我們首先要做的就是給這個(gè)頁(yè)面注冊(cè)導(dǎo)航

API

StackNavigator(RouteConfigs, StackNavigatorConfig)

StackNavigator函數(shù)中有兩個(gè)參數(shù):

RouteConfigs

StackNavigatorConfig

配置RouteConfigs

const RouteConfigs = {
  Home: {
    screen: TabBar // screen屬性為必須配置屬性
  },
  Home2: {
    screen: Home2,
    path:"app/Home2",
    navigationOptions: {
      title: "這是在RouteConfigs中設(shè)置的title",
      headerTitleStyle: {
        fontSize: 10
      }
    }
  },
  Home3: { screen: Home3 },
  Home4: { screen: Home4 },
  Home5: {screen: Home5},
  Home6: {screen: Home6},
  Home7: {screen: Home7},
  Setting2: {screen: Setting2},
  Setting3: {screen: Setting3},
}

配置StackNavigatorConfig

const StackNavigatorConfig = {
  initialRouteName: "Home",
  initialRouteParams: {initPara: "初始頁(yè)面參數(shù)"},
  navigationOptions: {
    title: "標(biāo)題",
    headerTitleStyle: {fontSize: 18, color: "red"},
    headerStyle: {height: 49},
  },
  paths: "page/main",
  mode: "card",
  headerMode: "screen",
  cardStyle: {backgroundColor: "#ffffff"},
  transitionConfig: (() => ({
  })),
  onTransitionStart: (() => {
    console.log("頁(yè)面跳轉(zhuǎn)動(dòng)畫(huà)開(kāi)始")
  }),
  onTransitionEnd: (() => {
    console.log("頁(yè)面跳轉(zhuǎn)動(dòng)畫(huà)結(jié)束")
  }),
}

注冊(cè)導(dǎo)航

import {StackNavigator, TabNavigator} from "react-navigation"

const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

export default class Main extends Component {
    render() {
        return (
            
        )
    }
}

從上面注冊(cè)導(dǎo)航的代碼塊中,我們可以看出StackNavigator函數(shù)接受兩個(gè)配置對(duì)象RouteConfigs StackNavigatorConfig ,但是這里需要注意,第二個(gè)參數(shù)StackNavigatorConfig可以省略,表示不做任何導(dǎo)航默認(rèn)配置

StackNavigatorConfig配置參數(shù)

initialRouteName :導(dǎo)航器組件中初始顯示頁(yè)面的路由名稱,如果不設(shè)置,則默認(rèn)第一個(gè)路由頁(yè)面為初始顯示頁(yè)面

initialRouteParams:給初始路由的參數(shù),在初始顯示的頁(yè)面中可以通過(guò)this.props.navigation.state.params來(lái)獲取

navigationOptions:路由頁(yè)面的全局配置項(xiàng)

paths :RouteConfigs里面路徑設(shè)置的映射

mode :頁(yè)面跳轉(zhuǎn)方式,有card和modal兩種,默認(rèn)為 card

card:普通app常用的左右切換

modal:只針對(duì)iOS平臺(tái),類似于iOS中的模態(tài)跳轉(zhuǎn),上下切換

headerMode :頁(yè)面跳轉(zhuǎn)時(shí),頭部的動(dòng)畫(huà)模式,有 float 、 screen 、 none 三種

float:漸變,類似iOS的原生效果,無(wú)透明,默認(rèn)方式

screen:標(biāo)題與屏幕一起淡入淡出,如微信QQ的一樣

none:沒(méi)有動(dòng)畫(huà)

cardStyle :為各個(gè)頁(yè)面設(shè)置統(tǒng)一的樣式,比如背景色,字體大小等

transitionConfig :配置頁(yè)面跳轉(zhuǎn)的動(dòng)畫(huà),覆蓋默認(rèn)的動(dòng)畫(huà)效果

onTransitionStart :頁(yè)面跳轉(zhuǎn)動(dòng)畫(huà)即將開(kāi)始時(shí)調(diào)用

onTransitionEnd :頁(yè)面跳轉(zhuǎn)動(dòng)畫(huà)一旦完成會(huì)馬上調(diào)用

在StackNavigatorConfig配置參數(shù)中有一個(gè)navigationOptions 屬性的配置,這個(gè)配置項(xiàng)可以理解為導(dǎo)航欄的全局配置表,下面就講解這個(gè)屬性的可配置參數(shù)

navigationOptions配置參數(shù)

title :導(dǎo)航欄的標(biāo)題,或者Tab標(biāo)題 tabBarLabel

header :自定義的頭部組件,使用該屬性后系統(tǒng)的頭部組件會(huì)消失,如果想在頁(yè)面中自定義,可以設(shè)置為null,這樣就不會(huì)出現(xiàn)頁(yè)面中留有一個(gè)高度為64navigationBar的高度

headerTitle :頭部的標(biāo)題,即頁(yè)面的標(biāo)題

headerBackTitle :返回標(biāo)題,默認(rèn)為 title的標(biāo)題

headerTruncatedBackTitle :返回標(biāo)題不能顯示時(shí)(比如返回標(biāo)題太長(zhǎng)了)顯示此標(biāo)題,默認(rèn)為"Back"

headerRight :頭部右邊組件

headerLeft :頭部左邊組件

headerStyle :頭部組件的樣式

headerTitleStyle :頭部標(biāo)題的樣式

headerBackTitleStyle :頭部返回標(biāo)題的樣式

headerTintColor :頭部顏色

headerPressColorAndroid :Android 5.0 以上MD風(fēng)格的波紋顏色

gesturesEnabled :否能側(cè)滑返回,iOS 默認(rèn) true , Android 默認(rèn) false

navigationOptions

// StackNavigatorConfig中的navigationOptions屬性也可以在組件內(nèi)用static navigationOptions 設(shè)置(會(huì)覆蓋此處的設(shè)置)
navigationOptions: { 
        header: {  // 導(dǎo)航欄相關(guān)設(shè)置項(xiàng)
            backTitle: "返回",  // 左上角返回鍵文字
            style: {
                backgroundColor: "#fff"
            },
            titleStyle: {
                color: "green"
            }
        },
        cardStack: {
            gesturesEnabled: true
        }
    }

注意:

我們也可以在RouteConfigs 中配置 navigationOptions屬性,我們也可以在多帶帶頁(yè)面配置navigationOptions

在頁(yè)面里面采用靜態(tài)的方式配置 navigationOptions屬性,會(huì)覆蓋StackNavigator函數(shù)中RouteConfigs StackNavigatorConfig 對(duì)象中的navigationOptions屬性里面的對(duì)應(yīng)屬性

navigationOptions中屬性的優(yōu)先級(jí)是:頁(yè)面中靜態(tài)配置 > RouteConfigs > StackNavigatorConfig

RouteConfigs 中配置 navigationOptions

const RouteConfigs = {
  Home: {
    screen: TabBar
  },
  Home2: {
    screen: Home2,
    path:"app/Home2",
   // 此處設(shè)置了, 會(huì)覆蓋組件內(nèi)的`static navigationOptions`設(shè)置. 具體參數(shù)詳見(jiàn)下文
    navigationOptions: {
      title: "這是在RouteConfigs中設(shè)置的title",
      headerTitleStyle: {
        fontSize: 10
      }
    }
  },
  Home3: { screen: Home3 },
  Home4: { screen: Home4 },
  Home5: {screen: Home5},
  Home6: {screen: Home6},
  Home7: {screen: Home7},
  Setting2: {screen: Setting2},
  Setting3: {screen: Setting3},
}

在具體頁(yè)面中配置 navigationOptions

import {StackNavigator, TabNavigator} from "react-navigation"

const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

export default class Main extends Component {

    // 配置頁(yè)面導(dǎo)航選項(xiàng)
    static navigationOptions = {
    title: "homeThree",
    header: (navigation, defaultHeader) => ({
      ...defaultHeader,  // 默認(rèn)預(yù)設(shè)
      visible: true  // 覆蓋預(yù)設(shè)中的此項(xiàng)
    }),
    cardStack: {
        gesturesEnabled: false  // 是否可以右滑返回
    }
}

    // 或這樣
    static navigationOptions = {
    // title: "Two", // 固定標(biāo)題
    title: (navigation, childRouter) => {  // 動(dòng)態(tài)標(biāo)題
        if (navigation.state.params.isSelected) {
            return `${navigation.state.params.name}選中`;
        } else {
            return `${navigation.state.params.name}沒(méi)選中`;
        }
    },
    header: ({ state, setParams, goBack }) => {
        let right;
        if (state.params.isSelected) {
            right = (
TabNavigator

API

TabNavigator(RouteConfigs, TabNavigatorConfig)

從API上看,TabNavigator 和 StackNavigator 函數(shù)用法一樣,都是接受RouteConfigs和TabNavigatorConfig這兩個(gè)參數(shù)

RouteConfigs配置參數(shù)

路由配置和StackNavigator中一樣,配置路由以及對(duì)應(yīng)的 screen 頁(yè)面,navigationOptions 為對(duì)應(yīng)路由頁(yè)面的配置選項(xiàng)

title :Tab標(biāo)題,可用作headerTitle 和 tabBarLabel 回退標(biāo)題

tabBarVisible :Tab的是否可見(jiàn),默認(rèn)為 true

tabBarIcon :Tab的icon組件,可以根據(jù) {focused: boolean, tintColor: string} 方法來(lái)返回一個(gè)icon組件

tabBarLabel :Tab中顯示的標(biāo)題字符串或者組件,也可以根據(jù){ focused: boolean, tintColor: string } 方法返回一個(gè)組件

配置RouteConfigs

const RouteConfigs = {
  Home: {
    screen: Home,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Home",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },
  People: {
    screen: People,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "People",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },
  Chat: {
    screen: Chat,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Chat",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },
  Setting: {
    screen: Setting,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Settings",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  }
}

TabNavigatorConfig配置參數(shù)

tabBarComponent : Tab選項(xiàng)卡組件,有TabBarBottom和TabBarTop兩個(gè)值,在iOS中默認(rèn)為 TabBarBottom ,在Android中默認(rèn)為 TabBarTop

TabBarTop:在頁(yè)面的頂部

TabBarBottom:在頁(yè)面的底部

tabBarPosition :Tab選項(xiàng)卡的位置,有top或bottom兩個(gè)值

top:上

bottom:下

swipeEnabled :是否可以滑動(dòng)切換Tab選項(xiàng)卡

animationEnabled :切換界面是否需要?jiǎng)赢?huà)

lazy :是否懶加載頁(yè)面

initialRouteName :初始顯示的Tab對(duì)應(yīng)的頁(yè)面路由名稱

order :用路由名稱數(shù)組來(lái)表示Tab選項(xiàng)卡的順序,默認(rèn)為路由配置順序

paths : 路徑配置

backBehavior :androd點(diǎn)擊返回鍵時(shí)的處理,有initialRoute 和 none 兩個(gè)值

initailRoute:返回初始界面

none:退出

tabBarOptions :Tab配置屬性,用在TabBarTop和TabBarBottom時(shí)有些屬性不一致

用在TabBarTop時(shí)對(duì)應(yīng)的屬性:

activeTintColor:選中的文字顏色

inactiveTintColor:未選中的文字顏色

showIcon:是否顯示圖標(biāo),默認(rèn)顯示

showLabel:是否顯示標(biāo)簽,默認(rèn)顯示

upperCaseLabel:是否使用大寫(xiě)字母,默認(rèn)使用

pressColor:android 5.0以上的MD風(fēng)格波紋顏色

pressOpacity:android 5.0以下或者iOS按下的透明度

scrollEnabled:是否可以滾動(dòng)

tabStyle:?jiǎn)蝹€(gè)Tab的樣式

indicatorStyle:指示器的樣式

labelStyle:標(biāo)簽的樣式

iconStyle:icon的樣式

style:整個(gè)TabBar的樣式

用在TabBarBottom時(shí)對(duì)應(yīng)的屬性:

activeTintColor:選中Tab的文字顏色

inactiveTintColor:未選中Tab的的文字顏色

activeBackgroundColor:選中Tab的背景顏色

inactiveBackgroundColor:未選中Tab的背景顏色

showLabel:是否顯示標(biāo)題,默認(rèn)顯示

style:整個(gè)TabBar的樣式

labelStyle:標(biāo)簽的樣式

tabStyle:?jiǎn)蝹€(gè)Tab的樣式

使用TabBarTop代碼示例

import React, {Component} from "react";
import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
export default class MainComponent extends Component {
    render() {
        return (
            
        );
    }
}

const TabRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: "首頁(yè)",
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: "附近",
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: "我的",
        },
    }
};
const TabNavigatorConfigs = {
    initialRouteName: "Home",
    tabBarComponent: TabBarTop,
    tabBarPosition: "top",
    lazy: true,
    tabBarOptions: {}
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
    Tab: {
        screen: Tab,
    }
};
const StackNavigatorConfigs = {
    initialRouteName: "Tab",
    navigationOptions: {
        title: "標(biāo)題",
        headerStyle: {backgroundColor: "#5da8ff"},
        headerTitleStyle: {color: "#333333"},
    }
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

使用TabBarBottom代碼示例

import React, {Component} from "react";
import {StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
import TabBarItem from "./index18/TabBarItem";
export default class MainComponent extends Component {
    render() {
        return (
            
        );
    }
}

const TabRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: "首頁(yè)",
            tabBarIcon: ({focused, tintColor}) => (
                
            ),
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: "附近",
            tabBarIcon: ({focused, tintColor}) => (
                
            ),
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: "我的",
            tabBarIcon: ({focused, tintColor}) => (
                
            ),
        },
    }
};
const TabNavigatorConfigs = {
    initialRouteName: "Home",
    tabBarComponent: TabBarBottom,
    tabBarPosition: "bottom",
    lazy: true,
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
    Tab: {
        screen: Tab,
    }
};
const StackNavigatorConfigs = {
    initialRouteName: "Tab",
    navigationOptions: {
        title: "標(biāo)題",
        headerStyle: {backgroundColor: "#5da8ff"},
        headerTitleStyle: {color: "#333333"},
    }
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
DrawerNavigator

API

DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)

DrawerNavigator StackNavigator TabNavigator 函數(shù)的使用方式一樣,參數(shù)配置也類似

路由配置和StackNavigator中一樣,配置路由以及對(duì)應(yīng)的 screen 頁(yè)面,navigationOptions 為對(duì)應(yīng)路由頁(yè)面的配置選項(xiàng)

RouteConfigs參數(shù)配置

title :抽屜標(biāo)題,和headerTitle 、 drawerLabel一樣

drawerLabel :標(biāo)簽字符串,或者自定義組件,可以根據(jù){ focused: boolean, tintColor: string } 函數(shù)來(lái)返回一個(gè)自定義組件作為標(biāo)簽

drawerIcon :抽屜icon,可以根據(jù) { focused: boolean, tintColor: string } 函數(shù)來(lái)返回一個(gè)自定義組件作為icon

DrawerNavigatorConfig參數(shù)配置

drawerWidth :抽屜寬度,可以使用Dimensions獲取屏幕的寬度動(dòng)態(tài)計(jì)算

drawerPosition :抽屜位置,可以是 left 或者 right

contentComponent :抽屜內(nèi)容組件,可以自定義側(cè)滑抽屜中的所有內(nèi)容,默認(rèn)為 DrawerItems

contentOptions :用來(lái)配置抽屜內(nèi)容的屬性。當(dāng)用來(lái)配置 DrawerItems 是配置屬性選項(xiàng)

items:抽屜欄目的路由名稱數(shù)組,可以被修改

activeItemKey:當(dāng)前選中頁(yè)面的key id

activeTintColor:選中條目狀態(tài)的文字顏色

activeBackgroundColor:選中條目的背景色

inactiveTintColor:未選中條目狀態(tài)的文字顏色

inactiveBackgroundColor:未選中條目的背景色

onItemPress(route) :條目按下時(shí)會(huì)調(diào)用此方法

style:抽屜內(nèi)容的樣式

labelStyle:抽屜的條目標(biāo)題/標(biāo)簽樣式

initialRouteName :初始化展示的頁(yè)面路由名稱

order :抽屜導(dǎo)航欄目順序,用路由名稱數(shù)組表示

paths :路徑

backBehavior :androd點(diǎn)擊返回鍵時(shí)的處理,有initialRoute和none兩個(gè)值

initailRoute:返回初始界面

none :退出

示例代碼

import React, {Component} from "react";
import {DrawerNavigator, StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
import TabBarItem from "./index18/TabBarItem";

const RouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            drawerLabel : "首頁(yè)",
            drawerIcon : ({focused, tintColor}) => (
                
            ),
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            drawerLabel : "附近",
            drawerIcon : ({focused, tintColor}) => (
                
            ),
        },
    },
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            drawerLabel : "我的",
            drawerIcon : ({focused, tintColor}) => (
                
            ),
        },
    }
};

const DrawerNavigatorConfigs = {
    initialRouteName: "Home",
    tabBarComponent: TabBarBottom,
    tabBarPosition: "bottom",
    lazy: true,
    tabBarOptions: {}
};

const Drawer = DrawerNavigator(RouteConfigs, DrawerNavigatorConfigs)

const StackRouteConfigs = {
    Drawer: {
        screen: Drawer,
    }
};

const StackNavigatorConfigs = {
    initialRouteName: "Drawer",
    navigationOptions: {
        title: "標(biāo)題",
        headerStyle: {backgroundColor: "#5da8ff"},
        headerTitleStyle: {color: "#333333"},
    }
}

const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs)

export default class Main extends Component {
    render() {
        return (
            
        )
    }
}
navigation

在StackNavigator中注冊(cè)過(guò)的組件都有navigation這個(gè)屬性,navigation有5個(gè)主要參數(shù)

navigate

state

setParams

goBack

dispatch

我們平時(shí)使用react-navigation作為導(dǎo)航組件來(lái)開(kāi)發(fā)時(shí),經(jīng)常使用到的也就是這5個(gè)屬性的功能

navigate

導(dǎo)航到下一個(gè)頁(yè)面

導(dǎo)航到下一個(gè)頁(yè)面并傳遞參數(shù)

navigation中的navigate函數(shù)可以接受三個(gè)參數(shù)

routeName :注冊(cè)過(guò)的目標(biāo)路由名稱,也就是準(zhǔn)備跳轉(zhuǎn)到的頁(yè)面路由地址(例如上面的Home3)

params :跳轉(zhuǎn)到下一個(gè)頁(yè)面,傳遞的參數(shù)(例如上面的id)

action :下文有講到

state

state屬性包含有傳遞過(guò)來(lái)的三個(gè)參數(shù) params、key 、routeName

routeName :注冊(cè)過(guò)的目標(biāo)路由名稱

key :路由身份標(biāo)識(shí)

params :跳轉(zhuǎn)時(shí)傳遞的參數(shù)

獲取state中的參數(shù):this.props.navigation.state.params.id 這樣就能拿到上一個(gè)頁(yè)面?zhèn)鬟f的參數(shù):id

setParams

this.props.navigation.setParams(): 該方法允許界面更改router中的參數(shù),可以用來(lái)動(dòng)態(tài)的更改導(dǎo)航欄的內(nèi)容。比如可以用來(lái)更新頭部的按鈕或者標(biāo)題等

使用場(chǎng)景:重寫(xiě)導(dǎo)航按鈕的返回按鈕,自定義返回事件

export default class Home5 extends Component {

  static navigationOptions = ({navigation, screenProps}) => ({
      title: "Home5",
      headerLeft: (
        

goBack

退出當(dāng)前頁(yè)面,返回到上一個(gè)頁(yè)面,可以不傳參數(shù),也可以傳參數(shù),還可以傳 null

this.props.navigation.goBack(); // 回退到上一個(gè)頁(yè)面

this.props.navigation.goBack(null); // 回退到任意一個(gè)頁(yè)面

this.props.navigation.goBack("Home"); // 回退到Home頁(yè)面

dispatch

this.props.navigation.dispatch: 可以dispatch一些action,主要支持的action有一下幾種

Navigate

import { NavigationActions } from "react-navigation"

  const navigationAction = 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(navigationAction)

Reset

Reset方法會(huì)清除原來(lái)的路由記錄,添加上新設(shè)置的路由信息, 可以指定多個(gè)action,index是指定默認(rèn)顯示的那個(gè)路由頁(yè)面, 注意不要越界了

import { NavigationActions } from "react-navigation"

  const resetAction = NavigationActions.reset({
    index: 0,
    actions: [
      NavigationActions.navigate({ routeName: "Profile"}),
      NavigationActions.navigate({ routeName: "Two"})
    ]
  })
  this.props.navigation.dispatch(resetAction)

SetParams

為指定的router更新參數(shù),該參數(shù)必須是已經(jīng)存在于router的param中

import { NavigationActions } from "react-navigation"

  const setParamsAction = NavigationActions.setParams({
    params: {}, // these are the new params that will be merged into the existing route params
    // The key of the route that should get the new params
    key: "screen-123",
  })
  this.props.navigation.dispatch(setParamsAction)

Back

NavigationActions.back()

Init

const initialState = Navigator.router.getStateForAction(NavigationActions.init());

export default (state = initialState, actions) => {
    const nextState = Navigator.router.getStateForAction(actions, state);
    return nextState || state;
}

注意: 如果你的項(xiàng)目中使用了與Redux框架結(jié)合,這里的dispatch就可以派發(fā)任何你想dispatch的Action了

使用場(chǎng)景:Counter 計(jì)數(shù)器

class Counter extends Component {

  static navigationOptions = () => ({
    title: "Counter加減計(jì)數(shù)器"
  })

  render() {
    const {dispatch} = this.props.navigation
    return (
      
        Counter
        {this.props.counterValue}
        
常用功能:頁(yè)面跳轉(zhuǎn)、頁(yè)面?zhèn)髦?、參?shù)回調(diào)

頁(yè)面跳轉(zhuǎn)與傳值

          

在下一界面接收參數(shù),通過(guò)this.props.navigation.state.params接收參數(shù)

export default class Home3 extends Component {

  render() {
    const {navigate} = this.props.navigation
    return (
      
        Home3
        {`Home界面?zhèn)鬟f的參數(shù)為:${this.props.navigation.state.params.id}`}
        

回調(diào)傳參

當(dāng)前界面進(jìn)行跳轉(zhuǎn),并傳遞參數(shù)

          

下一界面在返回之前執(zhí)行函數(shù)回調(diào)傳參給上一個(gè)頁(yè)面

    const {state, goBack} = this.props.navigation

        
DeepLink

其他app或?yàn)g覽器使用url打開(kāi)次app并進(jìn)入指定頁(yè)面,類似于iOS中的URL導(dǎo)航一樣。如瀏覽器輸入url OneM://home/home2直接進(jìn)入home2頁(yè)面

iOS平臺(tái)需要額外配置

在info.plist文件中設(shè)置Schemes,示例中的Schemes為:OneM

在AppDelegate添加代理函數(shù)

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  return [RCTLinkingManager application:application openURL:url
                      sourceApplication:sourceApplication annotation:annotation];
}

在js中配置

js組件在注冊(cè)路由時(shí)設(shè)置唯一的路徑path, 例如Home2: { screen: Home2, path:"home/Home2"}

在手機(jī)瀏覽器訪問(wèn)OneM://home/Home2, 彈窗選擇打開(kāi), 就可以打開(kāi)OneM app并進(jìn)到Home2頁(yè)面了

開(kāi)發(fā)中遇到的問(wèn)題及注意事項(xiàng)

默認(rèn)DrawerView不可滾動(dòng)。要實(shí)現(xiàn)可滾動(dòng)視圖,必須使用contentComponent自定義容器

{  
  drawerWidth:200, 
  contentComponent:props =>     
}

可以覆蓋導(dǎo)航使用的默認(rèn)組件,使用DrawerItems自定義導(dǎo)航組件

import {DrawerItems} from "react-navigation";  

const CustomDrawerContentComponent = (props) => (  
    
      
      
)

嵌套抽屜導(dǎo)航 如果嵌套DrawerNavigation,抽屜將顯示在父導(dǎo)航下方

適配頂部導(dǎo)航欄標(biāo)題

測(cè)試中發(fā)現(xiàn),在iphone上標(biāo)題欄的標(biāo)題為居中狀態(tài),而在Android上則是居左對(duì)齊。所以需要我們修改源碼,進(jìn)行適配
【node_modules – react-navigation – src – views – Header.js】的326行代碼處,修改為如下:

title: {  
   bottom: 0,  
   left: TITLE_OFFSET,  
   right: TITLE_OFFSET,  
   top: 0,  
   position: "absolute",  
   alignItems: "center",  
 } 

上面方法通過(guò)修改源碼的方式其實(shí)略有弊端,畢竟擴(kuò)展性不好。還有另外一種方式就是,在navigationOptions中設(shè)置headerTitleStyle的alignSelf為 ’ center ‘即可解決

去除返回鍵文字顯示

【node_modules – react-navigation – src – views – HeaderBackButton.js】的91行代碼處,修改為如下即可

{
   Platform.OS === "ios" &&  
     title &&  
       
       {backButtonTitle}  
     
  } 

將上述代碼刪除即可

動(dòng)態(tài)設(shè)置頭部按鈕事件

當(dāng)我們?cè)陬^部設(shè)置左右按鈕時(shí),肯定避免不了要設(shè)置按鈕的單擊事件,但是此時(shí)會(huì)有一個(gè)問(wèn)題,navigationOptions是被修飾為static類型的,所以我們?cè)诎粹o的onPress的方法中不能直接通過(guò)this來(lái)調(diào)用Component中的方法。如何解決呢?在官方文檔中,作者給出利用設(shè)置params的思想來(lái)動(dòng)態(tài)設(shè)置頭部標(biāo)題。那么我們可以利用這種方式,將單擊回調(diào)函數(shù)以參數(shù)的方式傳遞到params,然后在navigationOption中利用navigation來(lái)取出設(shè)置到onPress即可:

export default class Home5 extends Component {

  static navigationOptions = ({navigation, screenProps}) => ({
      title: "Home5",
      headerRight: (
        

結(jié)合BackHandler處理返回和點(diǎn)擊返回鍵兩次退出App效果

點(diǎn)擊返回鍵兩次退出App效果的需求屢見(jiàn)不鮮。相信很多人在react-navigation下實(shí)現(xiàn)該功能都遇到了很多問(wèn)題,例如,其他界面不能返回。也就是手機(jī)本身返回事件在react-navigation之前攔截了。如何結(jié)合react-natigation實(shí)現(xiàn)呢?和大家分享兩種實(shí)現(xiàn)方式:

在注冊(cè)StackNavigator的界面中,注冊(cè)BackHandler

componentWillMount(){  
    BackHandler.addEventListener("hardwareBackPress", this._onBackAndroid );  
}  


componentUnWillMount(){  
    BackHandler.addEventListener("hardwareBackPress", this._onBackAndroid);  
}  

_onBackAndroid=()=>{  
    let now = new Date().getTime();  
    if(now - lastBackPressed < 2500) {  
        return false;  
    }  
    lastBackPressed = now;  
    ToastAndroid.show("再點(diǎn)擊一次退出應(yīng)用",ToastAndroid.SHORT);  
    return true;  
} 

監(jiān)聽(tīng)react-navigation的Router

/** 
 * 處理安卓返回鍵 
 */  
const defaultStateAction = AppNavigator.router.getStateForAction;  
AppNavigator.router.getStateForAction = (action,state) => {  
    if(state && action.type === NavigationActions.BACK && state.routes.length === 1) {  
        if (lastBackPressed + 2000 < Date.now()) {  
            ToastAndroid.show(Constant.hint_exit,ToastAndroid.SHORT);  
            lastBackPressed = Date.now();  
            const routes = [...state.routes];  
            return {  
                ...state,  
                ...state.routes,  
                index: routes.length - 1,  
            };  
        }  
    }  
    return defaultStateAction(action,state);  
}

實(shí)現(xiàn)Android中界面跳轉(zhuǎn)左右切換動(dòng)畫(huà)

react-navigation在android中默認(rèn)的界面切換動(dòng)畫(huà)是上下。如何實(shí)現(xiàn)左右切換呢?很簡(jiǎn)單的配置即可:

import CardStackStyleInterpolator from "react-navigation/src/views/CardStackStyleInterpolator";  

然后在StackNavigator的配置下添加如下代碼:

transitionConfig:()=>({  
    screenInterpolator: CardStackStyleInterpolator.forHorizontal,  
}) 

解決快速點(diǎn)擊多次跳轉(zhuǎn)

當(dāng)我們快速點(diǎn)擊跳轉(zhuǎn)時(shí),會(huì)開(kāi)啟多個(gè)重復(fù)的界面,如何解決呢。其實(shí)在官方Git中也有提示,解決這個(gè)問(wèn)題需要修改react-navigation源碼:
找到scr文件夾中的addNavigationHelpers.js文件,替換為如下文本即可:

export default function(navigation: NavigationProp) {  
  // 添加點(diǎn)擊判斷  
  let debounce = true;  
  return {  
      ...navigation,  
      goBack: (key?: ?string): boolean =>  
          navigation.dispatch(  
              NavigationActions.back({  
                  key: key === undefined ? navigation.state.key : key,  
              }),  
          ),  
      navigate: (routeName: string,  
                 params?: NavigationParams,  
                 action?: NavigationAction,): boolean => {  
          if (debounce) {  
              debounce = false;  
              navigation.dispatch(  
                  NavigationActions.navigate({  
                      routeName,  
                      params,  
                      action,  
                  }),  
              );  
              setTimeout(  
                  () => {  
                      debounce = true;  
                  },  
              500,  
              );  
              return true;  
          }  
          return false;  
      },  
    /** 
     * For updating current route params. For example the nav bar title and 
     * buttons are based on the route params. 
     * This means `setParams` can be used to update nav bar for example. 
     */  
    setParams: (params: NavigationParams): boolean =>  
      navigation.dispatch(  
        NavigationActions.setParams({  
          params,  
          key: navigation.state.key,  
        }),  
      ),  
  }
}
待補(bǔ)充問(wèn)題

hook tabBar上點(diǎn)擊事件

Android物理返回鍵處理

navigator與tabBar嵌套

tabBar上添加badge

pop多層頁(yè)面

pop到指定頁(yè)面

navigator與抽屜嵌套使用

導(dǎo)航title 在Android 平臺(tái)上不居中顯示

雙擊物理鍵,退出app

懶加載tabbar上數(shù)據(jù)

針對(duì)上面的待補(bǔ)充問(wèn)題,下面來(lái)逐一解答

hook tabBar上點(diǎn)擊事件

有時(shí)我們點(diǎn)擊tabBar上的tab來(lái)切換頁(yè)面,但是在切換頁(yè)面之前我們想先做一些邏輯處理,然后在切換到tab頁(yè)面,這時(shí)我們就需要先hook到這個(gè)tab的點(diǎn)擊事件,下面代碼塊就是告訴你如何hook到tab的點(diǎn)擊事件,處理完事件在打開(kāi)tab頁(yè)面,這個(gè)使用具體使用方式在示例Demo中都有實(shí)際使用,不清楚的同學(xué)們直接去運(yùn)行示例項(xiàng)目了解即可
Chat: {
    screen: Chat,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Chat",
      tabBarOnPress: () => {
        Alert.alert(
            "注意!",
            "這里做了hook tabBar的點(diǎn)擊事件操作,我們可以hook到這個(gè)點(diǎn)擊事件,處理我們想要處理的業(yè)務(wù)后再打開(kāi) Chat這個(gè)頁(yè)面",
            [
              {text: "打開(kāi)tab頁(yè)面", onPress: () => navigation.navigate("Chat")},
              {text: "Cancel", onPress: () => console.log("Cancel Pressed"), style: "cancel"},
            ],
            { cancelable: false }
        )
      },
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },

Android物理返回鍵處理(待更新)

navigator與tabBar嵌套

navigator與tabBar嵌套 具體的結(jié)合使用方式示例Demo中有給出具體示例,這個(gè)同學(xué)們直接運(yùn)行示例Demo查看即可

tabBar上添加badge

之前有不少同學(xué)問(wèn)我,怎么給一個(gè)tabBar設(shè)置badge,前段時(shí)間由于太忙,一直沒(méi)有去處理這個(gè)問(wèn)題,后面去實(shí)現(xiàn)了下自定義badge,感覺(jué)還是挺簡(jiǎn)單的,因?yàn)閚avigation的tabBarItem本來(lái)就是支持自定義的,既然能夠自定義,那實(shí)現(xiàn)badge自然也是可行的了,下面就是具體實(shí)現(xiàn)代碼塊
People: {
    screen: People,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "People",
      tabBarIcon: ({ focused, tintColor }) => (
          
            
            
              10
            
          
      )
    }),
  },

pop多層頁(yè)面

有時(shí)候我們?cè)陂_(kāi)發(fā)的時(shí)候,難免會(huì)遇到在點(diǎn)擊返回按鈕的時(shí)候,想直接返回到指定的某一個(gè)頁(yè)面,而不是返回上一級(jí)頁(yè)面,這時(shí)我們就需要對(duì)goback()函數(shù)做些處理了,具體的代碼實(shí)現(xiàn)如下
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

const defaultStateAction = Navigator.router.getStateForAction;

Navigator.router.getStateForAction = (action, state) => {
  if (state && action.key && action.type === "Navigation/BACK") {
    const desiredRoute = state.routes.find((route) => route.routeName === action.key)
    if (desiredRoute) {
      const index = state.routes.indexOf(desiredRoute)
      const finalState = {
        ...state,
        routes: state.routes.slice(0, index + 1),
        index: index,
      };
      return finalState
    } else {
      if (state.routes.length > action.key) {
        const stacksLength = state.routes.length - action.key
        const stacks = state.routes.slice(0, stacksLength)
        const finalState = {
          ...state,
          routes: stacks,
          index: stacksLength - 1,
        };
        return finalState
      }
    }
  }
  return defaultStateAction(action, state)
}

pop到指定頁(yè)面

其實(shí)goback()函數(shù),是很容易的就可以做到返回到指定頁(yè)面,和返回指定層級(jí)的頁(yè)面的,并不像網(wǎng)上其他的文章說(shuō)的需要改源碼啊,或者是需要結(jié)合redux才能實(shí)現(xiàn)啊,并不是這樣的,只需要我們簡(jiǎn)單的維護(hù)下導(dǎo)航的路由棧即可解決問(wèn)題,這個(gè)其實(shí)和原生iOS中處理導(dǎo)航的棧管理是一個(gè)道理
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

const defaultStateAction = Navigator.router.getStateForAction;

Navigator.router.getStateForAction = (action, state) => {
  if (state && action.key && action.type === "Navigation/BACK") {
    const desiredRoute = state.routes.find((route) => route.routeName === action.key)
    if (desiredRoute) {
      const index = state.routes.indexOf(desiredRoute)
      const finalState = {
        ...state,
        routes: state.routes.slice(0, index + 1),
        index: index,
      };
      return finalState
    } else {
      if (state.routes.length > action.key) {
        const stacksLength = state.routes.length - action.key
        const stacks = state.routes.slice(0, stacksLength)
        const finalState = {
          ...state,
          routes: stacks,
          index: stacksLength - 1,
        };
        return finalState
      }
    }
  }
  return defaultStateAction(action, state)
}

navigator與抽屜嵌套使用

navigator與抽屜嵌套使用的方式,示例Demo中已經(jīng)有具體實(shí)現(xiàn)了,這個(gè)比較簡(jiǎn)單,就不做詳細(xì)解答了

導(dǎo)航title 在Android 平臺(tái)上不居中顯示

簡(jiǎn)書(shū)上面的開(kāi)發(fā)中遇到的問(wèn)題及注意事項(xiàng)中有講解決辦法,不過(guò)作者還是建議大家將導(dǎo)航欄封裝成一個(gè)組件,使用自定義的組件靈活性更高

雙擊物理鍵,退出app(待更新)

懶加載tabbar上數(shù)據(jù)

這個(gè)懶加載Tab,這個(gè)也沒(méi)有什么好解答的,官方已經(jīng)給我提供了設(shè)置屬性,我們只需要設(shè)置個(gè)屬性即可,具體代碼如下
const TabNavigatorConfigs = {
  initialRouteName: "Home",
  lazy: true,
  tabBarOptions: {
    activeTintColor: Platform.OS === "ios" ? "#e91e63" : "#fff",
  }
}
總結(jié)
react-navigation導(dǎo)航組件的API相對(duì)較多,如果小伙伴們看完講解還是不清楚如何使用,建議直接運(yùn)行Demo項(xiàng)目,邊調(diào)試邊理解。

針對(duì)之前很多同學(xué)反映出關(guān)于react-navigation 使用上遇到的一些問(wèn)題,上面基本上都逐一解答了,并且都在示例Demo實(shí)戰(zhàn)的測(cè)試過(guò)是可行方案,后期還有其他的小伙伴遇到使用上的問(wèn)題,歡迎進(jìn)群討論,或者是給我簡(jiǎn)書(shū)留言,謝謝大家的支持。

作者提供的Demo地址

https://github.com/guangqiang-liu/react-navigation-demo

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97454.html

相關(guān)文章

  • react-navigation使用小記(2) 自定義header菜單項(xiàng)

    摘要:使用實(shí)現(xiàn)菜單組件。日常廢話上一篇文章講了如何用創(chuàng)建各種自定義頭部。這篇水文講一下如何實(shí)現(xiàn)右部的菜單項(xiàng)。怎么實(shí)現(xiàn)自定義頭部右側(cè)很簡(jiǎn)單,配置的選項(xiàng),傳入我們的自定義組件即可。在配置時(shí),通過(guò)一個(gè)閉包保存菜單項(xiàng)的狀態(tài)。提一點(diǎn)菜單項(xiàng)的是。 使用react-navigation實(shí)現(xiàn)headerRight菜單組件。 日常廢話 上一篇文章講了如何用react-navigation創(chuàng)建各種自定義頭部(h...

    ixlei 評(píng)論0 收藏0
  • react-native, react-navigation, redux 學(xué)習(xí)筆記

    摘要:的使用用戶發(fā)出函數(shù)算出新的重新渲染三大原則單一數(shù)據(jù)源,利用的形式向下傳播數(shù)據(jù)流決定只讀,通過(guò)修改通過(guò)純函數(shù)來(lái)修改組件狀態(tài),是描述動(dòng)作的純函數(shù)連接和基于全局的,選擇我們要注入的不同的組件分開(kāi)把注入,讀取方法三劍客先確定一下初始狀 redux的使用 react-native, react, react-redux, react-navigaition, redux-thunk, redu...

    妤鋒シ 評(píng)論0 收藏0
  • #react-navigation# 學(xué)習(xí)重點(diǎn)記錄

    摘要:在上,掛鉤到硬件的返回按鈕,并在用戶按下返回按鈕時(shí)觸發(fā)方法,因此它的行為與用戶期望的相同。傳遞參數(shù)給路由有個(gè)知識(shí)點(diǎn)需要將參數(shù)包裝成一個(gè)對(duì)象,作為方法的第二個(gè)參數(shù)傳遞給路由。默認(rèn)情況下按照平臺(tái)慣例設(shè)置,所以在上標(biāo)題居中,在上左對(duì)齊。 push 和 navigate的區(qū)別 push: 每次調(diào)用 push 時(shí), 我們會(huì)向?qū)Ш蕉褩V刑砑有侣酚伞?navigate: 當(dāng)你調(diào)用 navigat...

    fyber 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<