react-navigation组件网上搜一搜好多好多,但是自己照着做还是会遇到各种问题各种坑。为了以后再用不会忘记在这里留下一份使用笔记,以供以后参考
1.从一个新项目开始
react-native init RnNavDemo
- 下载react-navigation
npm install --save react-navigation
打开package.json 在dependencies中有看到"react-navigation": "^1.0.0-beta.11" 就安装成功了,可以使用了
- 创建app.js(名字随便起,反正创建一个新的js文件就是了)
在app.js中创建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是通过普通的属性创建的Tabbar和导航
* 2、Test2是在页面中通过属性创建Tabbar和导航
* 3、Test3是通过封装navigationOptions实现Tabbar和导航的
*/
const MyTab = TabNavigator({
Test1: {
screen: Test1,
navigationOptions:({navigation,screenProps}) => ({
// StackNavigator 属性部分
// title:'Test1', 同步设置导航和tabbar文字,不推荐使用
headerTitle:'首页', // 只会设置导航栏文字,
// header:{}, // 可以自定义导航条内容,如果需要隐藏可以设置为null
// headerBackTitle:null, // 设置跳转页面左侧返回箭头后面的文字,默认是上一个页面的标题。可以自定义,也可以设置为null
// headerTruncatedBackTitle:'', // 设置当上个页面标题不符合返回箭头后的文字时,默认改成"返回"。
// headerRight:{}, // 设置导航条右侧。可以是按钮或者其他。
// headerLeft:{}, // 设置导航条左侧。可以是按钮或者其他。
headerStyle:{
backgroundColor:'#4ECBFC'
}, // 设置导航条的样式。如果想去掉安卓导航条底部阴影可以添加elevation: 0,iOS去掉阴影是。
headerTitleStyle:{
fontSize:30,
color:'white',
alignSelf:'center', //(坑1,不加这个安卓的title在左边的)
}, // 设置导航条文字样式。安卓上如果要设置文字居中,只要添加alignSelf:'center'就可以了
// headerBackTitleStyle:{}, // 设置导航条返回文字样式。
// headerTintColor:'green', // 设置导航栏文字颜色。总感觉和上面重叠了。
gesturesEnabled:true, // 是否支持滑动返回收拾,iOS默认支持,安卓默认关闭
// TabNavigator 属性部分
// title:'', 同上
tabBarVisible:true, // 是否隐藏标签栏。默认不隐藏(true)
tabBarIcon: (({tintColor,focused}) => {
return(
)
}), // 设置标签栏的图标。需要单独设置。
tabBarLabel:'首页', // 设置标签栏的title。推荐这个方式。
})
},
Test2: {
screen:Test2,
},
Test3:{
screen:Test3,
navigationOptions: ()=> TabOptions('我的',MainIcon,MainIcon,'我的'),
},
},{
tabBarPosition:'bottom', // 设置tabbar的位置,iOS默认在底部,安卓默认在顶部。(属性值:'top','bottom')
swipeEnabled:false, // 是否允许在标签之间进行滑动。
animationEnabled: false, // 是否在更改标签时显示动画。
lazy:true, // 是否根据需要懒惰呈现标签,而不是提前制作,意思是在app打开的时候将底部标签栏全部加载,默认false,推荐改成true哦。
initialRouteName:'', // 设置默认的页面组件
backBehavior:'none', // 按 back 键是否跳转到第一个Tab(首页), none 为不跳转
tabBarOptions:{
// iOS属性
// 因为第二个tabbar是在页面中创建的,所以前景色的设置对其无效,当然也可以通过设置tintColor使其生效
activeTintColor:'red', // label和icon的前景色 活跃状态下(选中)。
inactiveTintColor:'orange', // label和icon的前景色 不活跃状态下(未选中)。
activeBackgroundColor:'blue', //label和icon的背景色 活跃状态下(选中) 。
inactiveBackgroundColor:'green', // label和icon的背景色 不活跃状态下(未选中)。
showLabel:true, // 是否显示label,默认开启。
// style:{}, // tabbar的样式。
// labelStyle:{}, //label的样式。
// 安卓属性
// activeTintColor:'', // label和icon的前景色 活跃状态下(选中) 。
// inactiveTintColor:'', // label和icon的前景色 不活跃状态下(未选中)。
showIcon:true, // 是否显示图标,默认关闭。
// showLabel:true, //是否显示label,默认开启。
// style:{}, // tabbar的样式。
// labelStyle:{}, // label的样式。
upperCaseLabel:false, // 是否使标签大写,默认为true。
// pressColor:'', // material涟漪效果的颜色(安卓版本需要大于5.0)。
// pressOpacity:'', // 按压标签的透明度变化(安卓版本需要小于5.0)。
// scrollEnabled:false, // 是否启用可滚动选项卡。
// tabStyle:{}, // tab的样式。
// indicatorStyle:{}, // 标签指示器的样式对象(选项卡底部的行)。安卓底部会多出一条线,可以将height设置为0来暂时解决这个问题。
// labelStyle:{}, // label的样式。
// iconStyle:{}, // 图标的样式。
}
});
// 初始化StackNavigator
const MyNav = StackNavigator({
// 将TabNavigator包裹在StackNavigator里面可以保证跳转页面的时候隐藏tabbar
MyTab:{
screen:MyTab,
},
// 将需要跳转的页面注册在这里,全局才可以跳转
Detail1:{
screen:Detail1
},
Detail2:{
screen:Detail2,
},
},{
//安卓默认动画是从下到上弹出的,加上这句就和iOS一样的push效果(坑2)
transitionConfig:()=>({
screenInterpolator:CardStackStyleInterpolator.forHorizontal,
})
});
const TabOptions = (tabBarTitle,normalImage,selectedImage,navTitle) => {
// console.log(navigation);
const tabBarLabel = tabBarTitle;
const tabBarIcon = (({tintColor,focused})=> {
return(
)
});
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 (
Welcome to Test1 !
{
const { navigate } = this.props.navigation;
navigate('Detail1');
}}>
点我跳转到Detail1
当前页面的Tabbar是在App.js中通过最普通的方式自定义。
{
const { navigate } = this.props.navigation;//这是拿到当前页面属性中的navigate
navigate('Detail2');//跳转到Detail2页面
}}>
在Detail2中有reset和navigate的使用方法(点文字跳转)
);
}
}
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:(
navigation.state.params?navigation.state.params.navigatePress():null}>我的
),
});
componentDidMount(){
// 通过在componentDidMount里面设置setParams将title的值动态修改
this.props.navigation.setParams({
headerTitle:'Detail1',
navigatePress:this.navigatePress,
});
}
navigatePress = () => {
alert('点击headerRight');
}
render() {
return (
Welcome to Detail1!
{
const { navigate } = this.props.navigation;
navigate('Detail2');
}}>
跳转到Detail2
);
}
}
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';
//导入自定义的导航栏,在header中使用
import NavStyle from './NavStyle.js';
import { NavigationActions } from 'react-navigation'
//跳转到root页面(pop到mytab)
const resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'MyTab' })
]
});
//跳转到指定页面(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:(
navigation.state.params?navigation.state.params.navigatePress():null}/>
)
})
componentDidMount(){
// 通过在componentDidMount里面设置setParams将title的值动态修改
this.props.navigation.setParams({
navigatePress:this.navigatePress
});
}
//pop到上一页
navigatePress = () => {
const { goBack } = this.props.navigation;
goBack();
}
render() {
return (
Welcome to Detail2!
本页面的导航栏是纯自定义的,点击事件需要通过setParams来添加
);
}
}
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
},
});
demo地址https://github.com/tmd2013/react-navigation-use.git