react-navigation組件網(wǎng)上搜一搜好多好多,但是自己照著做還是會遇到各種問題各種坑漩勤。為了以后再用不會忘記在這里留下一份使用筆記,以供以后參考
1.從一個新項目開始
react-native init RnNavDemo
- 下載react-navigation
npm install --save react-navigation
打開package.json 在dependencies中有看到"react-navigation": "^1.0.0-beta.11" 就安裝成功了犯犁,可以使用了
- 創(chuàng)建app.js(名字隨便起,反正創(chuàng)建一個新的js文件就是了)
在app.js中創(chuàng)建tabbar和navigation
import {
Image,
StyleSheet,
Text,
AsyncStorage
} from 'react-native';
import {
StackNavigator,
TabNavigator,
} from 'react-navigation';
import React from 'react';
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
import Test1 from './Test1.js';
import Test2 from './Test2.js';
import Test3 from './Test3.js';
import Detail1 from './Detail1.js';
import Detail2 from './Detail2.js';
const ShiTuIcon = require('./resources/icon_tabbar_merchant_normal.png');
const MainIcon = require('./resources/Main.png');
/**
* 1割岛、Test1是通過普通的屬性創(chuàng)建的Tabbar和導(dǎo)航
* 2、Test2是在頁面中通過屬性創(chuàng)建Tabbar和導(dǎo)航
* 3诀蓉、Test3是通過封裝navigationOptions實(shí)現(xiàn)Tabbar和導(dǎo)航的
*/
const MyTab = TabNavigator({
Test1: {
screen: Test1,
navigationOptions:({navigation,screenProps}) => ({
// StackNavigator 屬性部分
// title:'Test1', 同步設(shè)置導(dǎo)航和tabbar文字,不推薦使用
headerTitle:'首頁', // 只會設(shè)置導(dǎo)航欄文字,
// header:{}, // 可以自定義導(dǎo)航條內(nèi)容栗竖,如果需要隱藏可以設(shè)置為null
// headerBackTitle:null, // 設(shè)置跳轉(zhuǎn)頁面左側(cè)返回箭頭后面的文字暑脆,默認(rèn)是上一個頁面的標(biāo)題『可以自定義添吗,也可以設(shè)置為null
// headerTruncatedBackTitle:'', // 設(shè)置當(dāng)上個頁面標(biāo)題不符合返回箭頭后的文字時,默認(rèn)改成"返回"份名。
// headerRight:{}, // 設(shè)置導(dǎo)航條右側(cè)碟联。可以是按鈕或者其他僵腺。
// headerLeft:{}, // 設(shè)置導(dǎo)航條左側(cè)玄帕。可以是按鈕或者其他想邦。
headerStyle:{
backgroundColor:'#4ECBFC'
}, // 設(shè)置導(dǎo)航條的樣式。如果想去掉安卓導(dǎo)航條底部陰影可以添加elevation: 0,iOS去掉陰影是委刘。
headerTitleStyle:{
fontSize:30,
color:'white',
alignSelf:'center', //(坑1丧没,不加這個安卓的title在左邊的)
}, // 設(shè)置導(dǎo)航條文字樣式。安卓上如果要設(shè)置文字居中锡移,只要添加alignSelf:'center'就可以了
// headerBackTitleStyle:{}, // 設(shè)置導(dǎo)航條返回文字樣式呕童。
// headerTintColor:'green', // 設(shè)置導(dǎo)航欄文字顏色∠海總感覺和上面重疊了夺饲。
gesturesEnabled:true, // 是否支持滑動返回收拾,iOS默認(rèn)支持施符,安卓默認(rèn)關(guān)閉
// TabNavigator 屬性部分
// title:'', 同上
tabBarVisible:true, // 是否隱藏標(biāo)簽欄往声。默認(rèn)不隱藏(true)
tabBarIcon: (({tintColor,focused}) => {
return(
<Image
source={!focused ? ShiTuIcon : ShiTuIcon}
style={[{height:35,width:35 }, {tintColor: tintColor}]}
/>
)
}), // 設(shè)置標(biāo)簽欄的圖標(biāo)。需要單獨(dú)設(shè)置戳吝。
tabBarLabel:'首頁', // 設(shè)置標(biāo)簽欄的title浩销。推薦這個方式。
})
},
Test2: {
screen:Test2,
},
Test3:{
screen:Test3,
navigationOptions: ()=> TabOptions('我的',MainIcon,MainIcon,'我的'),
},
},{
tabBarPosition:'bottom', // 設(shè)置tabbar的位置听哭,iOS默認(rèn)在底部慢洋,安卓默認(rèn)在頂部。(屬性值:'top'陆盘,'bottom')
swipeEnabled:false, // 是否允許在標(biāo)簽之間進(jìn)行滑動普筹。
animationEnabled: false, // 是否在更改標(biāo)簽時顯示動畫。
lazy:true, // 是否根據(jù)需要懶惰呈現(xiàn)標(biāo)簽隘马,而不是提前制作太防,意思是在app打開的時候?qū)⒌撞繕?biāo)簽欄全部加載,默認(rèn)false,推薦改成true哦祟霍。
initialRouteName:'', // 設(shè)置默認(rèn)的頁面組件
backBehavior:'none', // 按 back 鍵是否跳轉(zhuǎn)到第一個Tab(首頁)杏头, none 為不跳轉(zhuǎn)
tabBarOptions:{
// iOS屬性
// 因?yàn)榈诙€tabbar是在頁面中創(chuàng)建的盈包,所以前景色的設(shè)置對其無效,當(dāng)然也可以通過設(shè)置tintColor使其生效
activeTintColor:'red', // label和icon的前景色 活躍狀態(tài)下(選中)醇王。
inactiveTintColor:'orange', // label和icon的前景色 不活躍狀態(tài)下(未選中)呢燥。
activeBackgroundColor:'blue', //label和icon的背景色 活躍狀態(tài)下(選中) 。
inactiveBackgroundColor:'green', // label和icon的背景色 不活躍狀態(tài)下(未選中)寓娩。
showLabel:true, // 是否顯示label叛氨,默認(rèn)開啟。
// style:{}, // tabbar的樣式棘伴。
// labelStyle:{}, //label的樣式寞埠。
// 安卓屬性
// activeTintColor:'', // label和icon的前景色 活躍狀態(tài)下(選中) 。
// inactiveTintColor:'', // label和icon的前景色 不活躍狀態(tài)下(未選中)焊夸。
showIcon:true, // 是否顯示圖標(biāo)仁连,默認(rèn)關(guān)閉。
// showLabel:true, //是否顯示label阱穗,默認(rèn)開啟饭冬。
// style:{}, // tabbar的樣式。
// labelStyle:{}, // label的樣式揪阶。
upperCaseLabel:false, // 是否使標(biāo)簽大寫昌抠,默認(rèn)為true。
// pressColor:'', // material漣漪效果的顏色(安卓版本需要大于5.0)鲁僚。
// pressOpacity:'', // 按壓標(biāo)簽的透明度變化(安卓版本需要小于5.0)炊苫。
// scrollEnabled:false, // 是否啟用可滾動選項卡。
// tabStyle:{}, // tab的樣式冰沙。
// indicatorStyle:{}, // 標(biāo)簽指示器的樣式對象(選項卡底部的行)侨艾。安卓底部會多出一條線,可以將height設(shè)置為0來暫時解決這個問題倦淀。
// labelStyle:{}, // label的樣式蒋畜。
// iconStyle:{}, // 圖標(biāo)的樣式。
}
});
// 初始化StackNavigator
const MyNav = StackNavigator({
// 將TabNavigator包裹在StackNavigator里面可以保證跳轉(zhuǎn)頁面的時候隱藏tabbar
MyTab:{
screen:MyTab,
},
// 將需要跳轉(zhuǎn)的頁面注冊在這里撞叽,全局才可以跳轉(zhuǎn)
Detail1:{
screen:Detail1
},
Detail2:{
screen:Detail2,
},
},{
//安卓默認(rèn)動畫是從下到上彈出的姻成,加上這句就和iOS一樣的push效果(坑2)
transitionConfig:()=>({
screenInterpolator:CardStackStyleInterpolator.forHorizontal,
})
});
const TabOptions = (tabBarTitle,normalImage,selectedImage,navTitle) => {
// console.log(navigation);
const tabBarLabel = tabBarTitle;
const tabBarIcon = (({tintColor,focused})=> {
return(
<Image
source={!focused ? normalImage : selectedImage}
style={[{height:35,width:35 }, {tintColor: tintColor}]}
/>
)
});
const headerTitle = navTitle;
const headerTitleStyle = {fontSize:22,color:'white',alignSelf:'center'};
// header的style
const headerStyle = {backgroundColor:'#4ECBFC'};
const tabBarVisible = true;
// const header = null;
return {tabBarLabel,tabBarIcon,headerTitle,headerTitleStyle,headerStyle,tabBarVisible};
};
export default MyNav;
test1.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class Test1 extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to Test1 !
</Text>
<Text style={styles.instructions} onPress={()=>{
const { navigate } = this.props.navigation;
navigate('Detail1');
}}>
點(diǎn)我跳轉(zhuǎn)到Detail1
</Text>
<Text style={styles.instructions}>
當(dāng)前頁面的Tabbar是在App.js中通過最普通的方式自定義。
</Text>
<Text style={styles.instructions} onPress={()=>{
const { navigate } = this.props.navigation;//這是拿到當(dāng)前頁面屬性中的navigate
navigate('Detail2');//跳轉(zhuǎn)到Detail2頁面
}}>
在Detail2中有reset和navigate的使用方法(點(diǎn)文字跳轉(zhuǎn))
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
marginTop:10,
textAlign: 'center',
color: '#333333',
marginBottom: 5,
fontSize: 18,
},
});
Detail1.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class Detail1 extends Component {
static navigationOptions = ({navigation,screenProps}) => ({
// 這里面的屬性和App.js的navigationOptions是一樣的愿棋。
headerTitle:navigation.state.params?navigation.state.params.headerTitle:'Detail1',
headerRight:(
<Text style={{color:'red',marginRight:20}} onPress={()=>navigation.state.params?navigation.state.params.navigatePress():null}>我的</Text>
),
});
componentDidMount(){
// 通過在componentDidMount里面設(shè)置setParams將title的值動態(tài)修改
this.props.navigation.setParams({
headerTitle:'Detail1',
navigatePress:this.navigatePress,
});
}
navigatePress = () => {
alert('點(diǎn)擊headerRight');
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to Detail1!
</Text>
<Text style={styles.instructions} onPress={()=>{
const { navigate } = this.props.navigation;
navigate('Detail2');
}}>
跳轉(zhuǎn)到Detail2
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
fontSize:18
},
});
Detail2.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Button
} from 'react-native';
//導(dǎo)入自定義的導(dǎo)航欄科展,在header中使用
import NavStyle from './NavStyle.js';
import { NavigationActions } from 'react-navigation'
//跳轉(zhuǎn)到root頁面(pop到mytab)
const resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'MyTab' })
]
});
//跳轉(zhuǎn)到指定頁面(push到Detail1)
const navigateAction = NavigationActions.navigate({
routeName: 'Detail1',
params: {headerTitle:'hahaha'},
action: NavigationActions.navigate({ routeName: 'Detail1'})
})
export default class Detail2 extends Component {
static navigationOptions = ({navigation,screenProps}) => ({
// 這里面的屬性和App.js的navigationOptions是一樣的。
header:(
<NavStyle leftClick={()=>navigation.state.params?navigation.state.params.navigatePress():null}/>
)
})
componentDidMount(){
// 通過在componentDidMount里面設(shè)置setParams將title的值動態(tài)修改
this.props.navigation.setParams({
navigatePress:this.navigatePress
});
}
//pop到上一頁
navigatePress = () => {
const { goBack } = this.props.navigation;
goBack();
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to Detail2!
</Text>
<Text style={styles.instructions}>
本頁面的導(dǎo)航欄是純自定義的糠雨,點(diǎn)擊事件需要通過setParams來添加
</Text>
<Button title={'reset'} onPress={()=>{
this.props.navigation.dispatch(resetAction)
}} />
<Button title={'navigate'} onPress={()=>{
this.props.navigation.dispatch(navigateAction)
}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
fontSize:18
},
});