一、命令安裝
npm install react-navigation --save
該庫包含三類組件:
(1)StackNavigator:用來跳轉頁面和傳遞參數
(2)TabNavigator:類似底部導航欄,用來在同一屏切換不同頁面
(3)DrawerNavigator:側滑菜單導航欄,用於輕松設置帶抽屜的屏幕
二、react-navigation
1、StackNavigator屬性介紹
navigationOptions:配置StackNavigator的一些屬性。
title:標題,如果設置了這個導航欄和標簽欄的title就會變成一樣的,不推薦使用
header:可以設置一些導航的屬性,如果隱藏頂部導航欄只要將這個屬性設置為null
headerTitle:設置導航欄標題,推薦
headerBackTitle:設置跳轉頁面左側返回箭頭后面的文字,默認是上一個頁面的標題。可以自定義,也可以設置為null
headerTruncatedBackTitle:設置當上個頁面標題不符合返回箭頭后的文字時,默認改成"返回"
headerRight:設置導航條右側。可以是按鈕或者其他視圖控件
headerLeft:設置導航條左側。可以是按鈕或者其他視圖控件
headerStyle:設置導航條的樣式。背景色,寬高等
headerTitleStyle:設置導航欄文字樣式
headerBackTitleStyle:設置導航欄‘返回’文字樣式
headerTintColor:設置導航欄顏色
headerPressColorAndroid:安卓獨有的設置顏色紋理,需要安卓版本大於5.0
gesturesEnabled:是否支持滑動返回手勢,iOS默認支持,安卓默認關閉
screen:對應界面名稱,需要填入import之后的頁面
mode:定義跳轉風格
card:使用iOS和安卓默認的風格
modal:iOS獨有的使屏幕從底部畫出。類似iOS的present效果
headerMode:返回上級頁面時動畫效果
float:iOS默認的效果
screen:滑動過程中,整個頁面都會返回
none:無動畫
cardStyle:自定義設置跳轉效果
transitionConfig: 自定義設置滑動返回的配置
onTransitionStart:當轉換動畫即將開始時被調用的功能
onTransitionEnd:當轉換動畫完成,將被調用的功能
path:路由中設置的路徑的覆蓋映射配置
initialRouteName:設置默認的頁面組件,必須是上面已注冊的頁面組件
initialRouteParams:初始路由參數
StackNavigator(RouteConfigs, StackNavigatorConfig)
// 注冊導航
const Navs = StackNavigator({
Home: { screen: Tabs },
HomeTwo: {
screen: HomeTwo, // 必須, 其他都是非必須
path:'app/homeTwo', 使用url導航時用到, 如 web app 和 Deep Linking
navigationOptions: {} // 此處設置了, 會覆蓋組件內的`static navigationOptions`設置. 具體參數詳見下文
},
HomeThree: { screen: HomeThree },
HomeFour: { screen: HomeFour }
}, {
initialRouteName: 'Home', // 默認顯示界面
navigationOptions: { // 屏幕導航的默認選項, 也可以在組件內用 static navigationOptions 設置(會覆蓋此處的設置)
headerTitle: "首頁",//導航欄標題
headerBackTitle: null,//設置跳轉頁面左側返回箭頭后面的文字,默認是上一個頁面的標題。可以自定義,也可以設置為null
headerTintColor: "#333",//設置導航欄顏色
cardStack: {
gesturesEnabled: true//是否允許右滑返回,在iOS上默認為true,在Android上默認為false
}
},
mode: 'card', // 頁面切換模式, 左右是card(相當於iOS中的push效果), 上下是modal(相當於iOS中的modal效果)
headerMode: 'screen', // 導航欄的顯示模式, screen: 有漸變透明效果, float: 無透明效果, none: 隱藏導航欄
onTransitionStart: ()=>{ console.log('導航欄切換開始'); }, // 頁面切換開始時的回調函數
onTransitionEnd: ()=>{ console.log('導航欄切換結束'); } // 頁面切換結束時的回調函數
});
如果在StackNavigatorConfig里面配置了navigationOptions的一下參數,這些參數會作用與RouteConfigs里面的所有路由的子頁面,如果路由子頁面里面設置了static navigationOptions那么會覆蓋此處配置的全局參數
已經配置好導航器以及對應的路由頁面了,但是要完成頁面之間的跳轉,還需要 navigation。
navigation
在導航器中的每一個頁面,都有 navigation 屬性,該屬性有以下幾個屬性/方法:
navigate - 跳轉到其他頁面 state - 當前頁面導航器的狀態 setParams - 更改路由的參數 goBack - 返回 dispatch - 發送一個action
navigete
調用這個方法可以跳轉到導航器中的其他頁面,此方法有三個參數:
— routeName 導航器中配置的路由名稱
— params 傳遞參數到下一個頁面
— action action
比如: this.props.navigation.navigate('Find', {param: 'i am the param'});
state
state 里面包含有傳遞過來的參數 params 、 key 、路由名稱 routeName ,打印log可以看得到:
{
params: { param: 'i am the param' },
key: 'id-1500546317301-1',
routeName: 'Mine'
}
setParams
更改當前頁面路由的參數,比如可以用來更新頭部的按鈕或者標題。
componentDidMount() {
this.props.navigation.setParams({param:'i am the new param'})
}
goBack
回退,可以不傳,也可以傳參數,還可以傳 null 。
this.props.navigation.goBack(); // 回退到上一個頁面
this.props.navigation.goBack(null); // 回退到任意一個頁面
this.props.navigation.goBack('Home'); // 回退到Home頁面
2、TabNavigator屬性介紹
screen:和導航的功能是一樣的,對應界面名稱,可以在其他頁面通過這個screen傳值和跳轉。 navigationOptions:配置TabNavigator的一些屬性 title:標題,會同時設置導航條和標簽欄的title tabBarVisible:是否隱藏標簽欄。默認不隱藏(true) tabBarIcon:設置標簽欄的圖標。需要給每個都設置 tabBarLabel:設置標簽欄的title。推薦 導航欄配置 tabBarPosition:設置tabbar的位置,iOS默認在底部,安卓默認在頂部。(屬性值:'top','bottom') swipeEnabled:是否允許在標簽之間進行滑動 animationEnabled:是否在更改標簽時顯示動畫 lazy:是否根據需要懶惰呈現標簽,而不是提前,意思是在app打開的時候將底部標簽欄全部加載,默認false,推薦為true trueinitialRouteName: 設置默認的頁面組件 backBehavior:按 back 鍵是否跳轉到第一個Tab(首頁), none 為不跳轉 tabBarOptions:配置標簽欄的一些屬性iOS屬性 activeTintColor:label和icon的前景色 活躍狀態下 activeBackgroundColor:label和icon的背景色 活躍狀態下 inactiveTintColor:label和icon的前景色 不活躍狀態下 inactiveBackgroundColor:label和icon的背景色 不活躍狀態下 showLabel:是否顯示label,默認開啟 style:tabbar的樣式 labelStyle:label的樣式安卓屬性 activeTintColor:label和icon的前景色 活躍狀態下 inactiveTintColor:label和icon的前景色 不活躍狀態下 showIcon:是否顯示圖標,默認關閉 showLabel:是否顯示label,默認開啟 style:tabbar的樣式 labelStyle:label的樣式 upperCaseLabel:是否使標簽大寫,默認為true pressColor:material漣漪效果的顏色(安卓版本需要大於5.0) pressOpacity:按壓標簽的透明度變化(安卓版本需要小於5.0) scrollEnabled:是否啟用可滾動選項卡 tabStyle:tab的樣式 indicatorStyle:標簽指示器的樣式對象(選項卡底部的行)。安卓底部會多出一條線,可以將height設置為0來暫時解決這個問題 labelStyle:label的樣式 iconStyle:圖標樣式
3、DrawerNavigator屬性介紹
DrawerNavigatorConfig
drawerWidth - 抽屜的寬度
drawerPosition - 選項是左或右。 默認為左側位置
contentComponent - 用於呈現抽屜內容的組件,例如導航項。 接收抽屜的導航。 默認為DrawerItems
contentOptions - 配置抽屜內容
initialRouteName - 初始路由的routeName
order - 定義抽屜項目順序的routeNames數組。
路徑 - 提供routeName到路徑配置的映射,它覆蓋routeConfigs中設置的路徑。
backBehavior - 后退按鈕是否會切換到初始路由? 如果是,設置為initialRoute,否則為none。 默認為initialRoute行為
DrawerItems的contentOptions屬性
activeTintColor - 活動標簽的標簽和圖標顏色
activeBackgroundColor - 活動標簽的背景顏色
inactiveTintColor - 非活動標簽的標簽和圖標顏色
inactiveBackgroundColor - 非活動標簽的背景顏色
內容部分的樣式樣式對象
labelStyle - 當您的標簽是字符串時,要覆蓋內容部分中的文本樣式的樣式對象
4、使用StackNavigator + TabNavigator實現Tab界面切換、界面間導航
1>首先導入必要組件(包含導航路由)
import { StackNavigator, TabNavigator, TabBarBottom } from "react-navigation";
import Home from "./category/Home";
import Feedback from "./category/feedback/feedback";
import Task from "./category/task/taskHome";
2>定義TabNavigator
const MyTab = TabNavigator(
{
Home: {
screen: Home,
navigationOptions: ({ navigation }) => ({
headerTitle: "首頁",
tabBarLabel: "首頁",
headerBackTitle: null,
tabBarIcon: ({ tintColor }) => (
<Image
style={styles.imageStyle}
source={
tintColor == "#ff552e"
? require("./img/yingxiao/ac-jingxuan.png")
: require("./img/yingxiao/jingxuan.png")
}
/>
)
})
},
Feed: {
screen: Feedback,
navigationOptions: ({ navigation }) => ({
headerTitle: "意見反饋",
tabBarLabel: "我的",
headerBackTitle: null,
headerRight: (
<Text
style={{ color: "#333", marginRight: 14, fontSize: 16 }}
onPress={() =>
navigation.state.params ? navigation.state.params.submit() : null
}>
提交
</Text>
),
tabBarIcon: ({ tintColor }) => (
<Image
style={styles.imageStyle}
source={
tintColor == "#ff552e"
? require("./img/yingxiao/ac-laidiantong.png")
: require("./img/yingxiao/laidiantong.png")
}
/>
)
})
}
},
{
tabBarComponent: TabBarBottom,
tabBarPosition: "bottom", //設置tabbar的位置,iOS默認在底部,安卓默認在頂部。(屬性值:'top','bottom')
swipeEnabled: true, //是否允許在標簽之間滑動
animationEnabled: false, //是否在更改標簽時顯示動畫
lazy: true, //是否根據需要懶惰呈現標簽,而不是提前制作,意思是在app打開的時候將底部標簽欄全部加載,默認false,推薦改成true
tabBarOptions: {
activeTintColor: "#ff552e", //label和icon的前景色 活躍狀態下(選中)
// activeBackgroundColor:'blue',//label和icon的背景色 活躍狀態下
inactiveTintColor: "#333", //label和icon的前景色 不活躍狀態下
showLabel: true, //是否顯示label,默認開啟
showIcon: true, // android 默認不顯示 icon, 需要設置為 true 才會顯示
style: { backgroundColor: "#ffffff" }, //tabbar的樣式
labelStyle: {
fontSize: 14 // 文字大小
}
}
}
);
3>定義StackNavigator
效果圖:
const AppIndex = StackNavigator({
Main: {
screen: MyTab
},
Task: {
screen: Task,
navigationOptions: {
headerBackTitle: null
}
}
});


任務系統導航跳轉到任務首頁:

難點:導航右側配置按鈕:
headerRight:設置導航條右側。可以是按鈕或者其他視圖控件
onPress = {()=>this.share()}
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.params.title}`,
headerBackTitle: `${navigation.state.params.title}`,
headerRight: (
<View style={{ flexDirection: "row" }}>
<Text
style={{ color: "#333", marginRight: 13 }}
// static里面不能使用this調用方法,出現share is not function
onPress={()=>this.share()
}>
分享
</Text>
</View>
)
});
解決辦法:
//右側配置兩個按鈕
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.params.title}`,
headerBackTitle: `${navigation.state.params.title}`,
headerRight: (
<View style={{ flexDirection: "row" }}>
<Text
style={{ color: "#333", marginRight: 13 }}
onPress={() =>
navigation.state.params ? navigation.state.params.share() : null
}>
分享
</Text>
<Text
style={{ color: "#333", marginRight: 13 }}
onPress={() =>
navigation.state.params ? navigation.state.params.jumpToRule() : null
}>
兌換規則
</Text>
</View>
)
});
例如分享:
首先在本類中聲明一個share(){
}的方法
頁面掛載完成在componentDidMount里面設置navigation的setParams把方法注入到navigation中去
componentDidMount() {
// 通過在componentDidMount里面設置setParams
this.props.navigation.setParams({
share: this.share
});
}
然后點擊時直接在navigation中尋找剛剛注入的放置直接調用
onPress={() =>
navigation.state.params ? navigation.state.params.share() : null
}
本人開發中最初的處理方式:
把導航里面配置的按鈕需要調用的本類函數放到window全局對象下面,然后在全局里面尋找調用

