本文內(nèi)容
1、navigation、tabbar 的分離、navigation的使用
2、傳值、回調(diào)
3、每個頁面設(shè)置 navigator
4、navigation reset方法
5、關(guān)于返回指定頁面(原)
5、關(guān)于返回指定頁面(新)
程序目錄

3D6B6EE2-5488-4648-811B-A2A7F5E06322.png
一、navigation、tabbar 的分離、navigation的使用
index.ios.js
require('./AppRoot/root');
root.js
/**
* Created by mymac on 2017/8/18.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import {StackNavigator} from "react-navigation";
import Navigator from './natigation';
/*
navigation 構(gòu)造函數(shù)
*/
const Navigation = StackNavigator(Navigator.AppNavigationRouterConfigs, Navigator.AppNavigationStackConfigs);
class MainComponent extends Component {
render() {
return (
<Navigation
onNavigationStateChange={(prevNav, nav, action)=>{
// 每次導(dǎo)航改變時,都會走這個方法,可以再次判斷邏輯
console.log('prevNav=',prevNav);
console.log('nav=',nav);
console.log('action=',action);
/>
);
}
}
AppRegistry.registerComponent('Navigation', () => MainComponent);
navigation.js
/**
* Created by mymac on 2017/8/18.
*/
import {TabNavigator} from "react-navigation";
import FirstCtrl from '../controllers/firstCtrl';
import SecondCtrl from '../controllers/secondCtrl';
import ThirdCtrl from '../controllers/thirdCtrl';
import AppTab from './tabBar';
// 動畫效果
// forHorizontal:從右向左進(jìn)入
// forVertical:從下向上進(jìn)入
// forFadeFromBottomAndroid:從底部淡出
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
/*
title - 可以作為頭部標(biāo)題 headerTitle ,或者Tab標(biāo)題 tabBarLabel
header - 自定義的頭部組件,使用該屬性后系統(tǒng)的頭部組件會消失
headerTitle - 頭部的標(biāo)題,即頁面的標(biāo)題
headerBackTitle - 返回標(biāo)題,默認(rèn)為 title
headerTruncatedBackTitle - 返回標(biāo)題不能顯示時(比如返回標(biāo)題太長了)顯示此標(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
*/
/*
構(gòu)造函數(shù)
*/
const Tab = TabNavigator(AppTab.AppRootTabBarRouteConfigs, AppTab.AppRootTabBarNavigatorConfigs);
/* 配置路由,所有要跳轉(zhuǎn)的頁面都需要在此聲明 */
const AppNavigationRouterConfigs = {
TabBar: {
screen: Tab,
navigationOptions: ({navigation}) => ({
title: '首頁',
headerBackTitle: '首頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題 , 類似iOS的 backBarItem
}),
},
First: {
screen: FirstCtrl,
navigationOptions: ({navigation}) => ({
title: '第一頁',
headerBackTitle: '第一頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題
}),
},
Second: {
screen: SecondCtrl,
navigationOptions: ({navigation}) => ({
title: '第二頁',
headerBackTitle: '第二頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題
}),
},
Third: {
screen: ThirdCtrl,
navigationOptions: ({navigation}) => ({
title: '第三頁',
headerBackTitle: '第三頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題
}),
}
};
/*
initialRouteName - 導(dǎo)航器組件中初始顯示頁面的路由名稱,如果不設(shè)置,則默認(rèn)第一個路由頁面為初始顯示頁面
initialRouteParams - 給初始路由的參數(shù),在初始顯示的頁面中可以通過 this.props.navigation.state.params 來獲取
navigationOptions - 路由頁面的配置選項(xiàng),它會被 RouteConfigs 參數(shù)中的 navigationOptions 的對應(yīng)屬性覆蓋。
paths - 路由中設(shè)置的路徑的覆蓋映射配置
mode - 頁面跳轉(zhuǎn)方式,有 card 和 modal 兩種,默認(rèn)為 card :
card - 原生系統(tǒng)默認(rèn)的的跳轉(zhuǎn)
modal - 只針對iOS平臺,模態(tài)跳轉(zhuǎn)
headerMode - 頁面跳轉(zhuǎn)時,頭部的動畫模式,有 float 、 screen 、 none 三種:
float - 漸變,類似iOS的原生效果
screen - 標(biāo)題與屏幕一起淡入淡出
none - 沒有動畫
cardStyle - 為各個頁面設(shè)置統(tǒng)一的樣式,比如背景色,字體大小等
transitionConfig - 配置頁面跳轉(zhuǎn)的動畫,覆蓋默認(rèn)的動畫效果
onTransitionStart - 頁面跳轉(zhuǎn)動畫即將開始時調(diào)用
onTransitionEnd - 頁面跳轉(zhuǎn)動畫一旦完成會馬上調(diào)用
*/
const AppNavigationStackConfigs = {
initialRouteName: 'TabBar',
initialRouteParams: {initParams: '初始化時傳遞參數(shù)'},
navigationOptions: {
title: '路由頁面的配置選項(xiàng),它會被 RouteConfigs 參數(shù)中的 navigationOptions 的對應(yīng)屬性覆蓋',
},
mode: 'card',
headerMode: 'screen',
transitionConfig: ()=>({
screenInterpolator: CardStackStyleInterpolator.forHorizontal,
}),
onTransitionStart: (() => {
console.log('頁面跳轉(zhuǎn)動畫開始');
}),
onTransitionEnd: (() => {
console.log('頁面跳轉(zhuǎn)動畫結(jié)束');
}),
};
export default {
AppNavigationRouterConfigs,
AppNavigationStackConfigs
};
tabBar.js
/**
* Created by mymac on 2017/8/18.
*/
import React, { Component } from 'react';
import {TabBarBottom} from "react-navigation";
import Home from '../subTabBars/select';
import Follow from '../subTabBars/follow';
import Explor from '../subTabBars/explor';
import Mine from '../subTabBars/mine';
/*自定義的 tabBar 圖片 view*/
import TabBarItem from './tabBarItem';
/*
創(chuàng)建下面的四個 tabar
*/
const AppRootTabBarRouteConfigs = {
Home:{
screen: Home,
navigationOptions: {
tabBarLabel: '首頁',
tabBarIcon: ({focused, tintColor}) => (
<TabBarItem
focused={focused}
normalImage={require('../images/select.png')}
selectedImage={require('../images/select_select.png')}
/>
),
}
},
Follow:{
screen: Follow,
navigationOptions: {
tabBarLabel: '關(guān)注',
tabBarIcon: ({focused, tintColor}) => (
<TabBarItem
focused={focused}
normalImage={require('../images/follow_follow.png')}
selectedImage={require('../images/follow_follow_select.png')}
/>
),
tabBarOnPress:(obj)=>{
console.log(obj);
obj.jumpToIndex(obj.scene.index)
},
}
},
Explor:{
screen: Explor,
navigationOptions: {
tabBarLabel: '發(fā)現(xiàn)',
tabBarIcon: ({focused, tintColor}) => (
<TabBarItem
focused={focused}
normalImage={require('../images/explor_explor.png')}
selectedImage={require('../images/explor_explor_select.png')}
/>
),
}
},
Mine:{
screen: Mine,
navigationOptions: {
tabBarLabel: '我的',
tabBarIcon: ({focused, tintColor}) => (
<TabBarItem
focused={focused}
normalImage={require('../images/mine_mine.png')}
selectedImage={require('../images/mine_mine_select.png')}
/>
),
}
},
};
/*
tabBarComponent - Tab選項(xiàng)卡組件,有 TabBarBottom 和 TabBarTop 兩個值,在iOS中默認(rèn)為 TabBarBottom ,在Android中默認(rèn)為 TabBarTop 。
TabBarTop - 在頁面的頂部
TabBarBottom - 在頁面的底部
tabBarPosition - Tab選項(xiàng)卡的位置,有 top 或 bottom 兩個值
swipeEnabled - 是否可以滑動切換Tab選項(xiàng)卡
animationEnabled - 點(diǎn)擊Tab選項(xiàng)卡切換界面是否需要動畫
lazy - 是否懶加載頁面
initialRouteName - 初始顯示的Tab對應(yīng)的頁面路由名稱
order - 用路由名稱數(shù)組來表示Tab選項(xiàng)卡的順序,默認(rèn)為路由配置順序
paths - 路徑配置
backBehavior - androd點(diǎn)擊返回鍵時的處理,有 initialRoute 和 none 兩個值
initailRoute - 返回初始界面
none - 退出
tabBarOptions - Tab配置屬性,用在 TabBarTop 和 TabBarBottom 時有些屬性不一致:
用于 TabBarTop 時:
activeTintColor - 選中的文字顏色
inactiveTintColor - 未選中的文字顏色
showIcon - 是否顯示圖標(biāo),默認(rèn)顯示
showLabel - 是否顯示標(biāo)簽,默認(rèn)顯示
upperCaseLabel - 是否使用大寫字母,默認(rèn)使用
pressColor - android 5.0以上的MD風(fēng)格波紋顏色
pressOpacity - android 5.0以下或者iOS按下的透明度
scrollEnabled - 是否可以滾動
tabStyle - 單個Tab的樣式
indicatorStyle - 指示器的樣式
labelStyle - 標(biāo)簽的樣式
iconStyle - icon的樣式
style - 整個TabBar的樣式
用于 TabBarBottom 時:
activeTintColor - 選中Tab的文字顏色
activeBackgroundColor - 選中Tab的背景顏色
inactiveTintColor - 未選中Tab的的文字顏色
inactiveBackgroundColor - 未選中Tab的背景顏色
showLabel - 是否顯示標(biāo)題,默認(rèn)顯示
style - 整個TabBar的樣式
labelStyle - 標(biāo)簽的樣式
tabStyle - 單個Tab的樣式
*/
/*
TabBarTop:
indicatorStyle: {height: 0}, // android 中TabBar下面會顯示一條線,高度設(shè)為 0 后就不顯示線了, 不知道還有沒有其它方法隱藏???
showIcon: true, // android 默認(rèn)不顯示 icon, 需要設(shè)置為 true 才會顯示
*/
const AppRootTabBarNavigatorConfigs = {
initialRouteName: 'Home',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
lazy: true,
tabBarOptions: {
activeTintColor: 'red',
inactiveTintColor: 'black',
showLabel: true,
style:{ // 在此處可以設(shè)置tabbar的屬性,height、marginBottom等。iPhone X適配時,需要在此處進(jìn)行適配處理
backgroundColor: 'yellow',
},
labelStyle: { // 在此處可以設(shè)置tabbar的title的屬性,大小、顏色等
fontWeight: 'bold',
fontSize: 12,
},
iconStyle: {
// 在此處可以設(shè)置tabbar的icon的屬性
}
}
};
export default {
AppRootTabBarRouteConfigs,
AppRootTabBarNavigatorConfigs
};
/* 在此直接導(dǎo)出 Tab ,在 navigation 里面是得不到的,只有在 navigation 里面 調(diào)用構(gòu)造方法*/
/*
構(gòu)造函數(shù)
export default Tab = TabNavigator(AppTab.AppRootTabBarRouteConfigs, AppTab.AppRootTabBarNavigatorConfigs);
*/
二、傳值、回調(diào)
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
} from 'react-native';
export default class select extends Component {
render() {
const {navigate,} = this.props.navigation;
return (
<View style={styles.container}>
<Text style={styles.welcome}>
精選
</Text>
<TouchableOpacity style={{marginTop: 20}} onPress={()=>{
// 傳遞參數(shù),及 回調(diào)函數(shù)
navigate('First', {params: '你好第一頁', callBack:(value)=>{
console.log(value);
}});
}}>
<Text style={styles.welcome}>
點(diǎn)擊跳轉(zhuǎn)到第一個頁面
</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
/**
* Created by mymac on 2017/8/18.
*/
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
export default class firstCtrl extends Component {
render() {
const {navigate} = this.props.navigation;
// 收到的參數(shù)
const {params} = this.props.navigation.state;
return (
<View style={styles.container}>
<Text style={styles.welcome}>
上一個頁面給當(dāng)前頁傳值為:{params.params}
</Text>
<TouchableOpacity style={{marginTop: 20}} onPress={()=>{
navigate('Second', {params: '你好第二頁'});
}}>
<Text style={styles.welcome}>
點(diǎn)擊跳轉(zhuǎn)到第二個頁面
</Text>
</TouchableOpacity>
<TouchableOpacity style={{marginTop: 100}} onPress={()=>{
//回調(diào)函數(shù)
params.callBack('123456789');
this.props.navigation.goBack();
}}>
<Text style={styles.welcome}>
點(diǎn)擊返回首頁,并傳值:"hello world"
</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
三、每個頁面設(shè)置 navigator
* Created by mymac on 2017/8/18.
*/
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
export default class firstCtrl extends Component {
/*
title - 可以作為頭部標(biāo)題 headerTitle ,或者Tab標(biāo)題 tabBarLabel
header - 自定義的頭部組件,使用該屬性后系統(tǒng)的頭部組件會消失
headerTitle - 頭部的標(biāo)題,即頁面的標(biāo)題
headerBackTitle - 返回標(biāo)題,默認(rèn)為 title
headerTruncatedBackTitle - 返回標(biāo)題不能顯示時(比如返回標(biāo)題太長了)顯示此標(biāo)題,默認(rèn)為 “Back”
headerRight - 頭部右邊組件
headerLeft - 頭部左邊組件
headerStyle - 頭部組件的樣式
headerTitleStyle - 頭部標(biāo)題的樣式
headerBackTitleStyle - 頭部返回標(biāo)題的樣式
headerTintColor - 頭部標(biāo)題顏色
headerPressColorAndroid - Android 5.0 以上MD風(fēng)格的波紋顏色
gesturesEnabled - 否能側(cè)滑返回, iOS 默認(rèn) true , Android 默認(rèn) false
*/
/*
static navigationOptions = ({ navigation, navigationOptions, screenProps }) => {
return {
title: navigation.getParam('otherParam', 'A Nested Details Screen'),
headerRight: (
<Text>right</Text>
),
headerTitle: <customTitle/> 自定義標(biāo)題組件。
};
};
*/
static navigationOptions = {
title:'第一個頁面自定義標(biāo)題', // 或者 headerTitle:'第一個頁面自定義標(biāo)題'
headerRight: (
<Text>right</Text>
),
//headerLeft: null, 沒有返回按鈕
headerTintColor: 'red',
header:null, // 隱藏 導(dǎo)航條
};
render() {
return (
<View style={styles.container}>
</View>
);
}
}
四、navigation reset方法
import { NavigationActions } from 'react-navigation'
重新注冊導(dǎo)航棧,將原來的清空
const resetAction = NavigationActions.reset({
index: 0, // 默認(rèn)選中第一個元素
actions: [
NavigationActions.navigate({ routeName: 'Profile'}) // Profile將這個js放入導(dǎo)航棧中
]
})
this.props.navigation.dispatch(resetAction)
import { NavigationActions } from 'react-navigation'
const resetAction = NavigationActions.reset({
index: 1, // 默認(rèn)選中第二個 元素, 如果此處寫為 2 這越界了,因?yàn)橄旅鏃@镏挥袃蓚€元素
actions: [
NavigationActions.navigate({ routeName: 'Profile'}), // Profile將這個js放入導(dǎo)航棧中,第一個元素
NavigationActions.navigate({ routeName: 'Settings'}) // Settings將這個js放入導(dǎo)航棧中,第二個元素
]
})
this.props.navigation.dispatch(resetAction)
5、關(guān)于返回指定頁面(原)
原思路:每一個頁面進(jìn)行navigate的時候都有一個key,所以在使用goBack(key)的時候,只要知道要返回頁面的key就可以了。方法就是把頁面的key存起來,存在redux中
<Navigation onNavigationStateChange={(prevNav, nav, action)=>{
// 每次導(dǎo)航改變時,都會走這個方法,可以再次判斷邏輯,比如切換tabar需要調(diào)用方法
console.log('prevNav=',prevNav);
console.log('nav=',nav);
console.log('action=',action);
let route = {};
nav.routes.map((item)=>{
route[item.routeName] = item.key
});
console.log('route:',route);
this.props.saveRouteNameAndId(route);
}}/>
5、關(guān)于返回指定頁面(新),請更新react-navigation到最新
再也不用去存key啦~
this.props.navigation 提供的幾種方法:
goBack
navigate
pop
popToTop
getParam
push
replace
this.props.navigation.pop(2) // 2就是要返回幾個頁面
this.props.navigation.popToTop() // 直接返回到主導(dǎo)航
this.props.navigation.push('HomeDetail1') // push 和 navigate效果一樣