一、简介
根据React Navigation官网文档描述:Learn once, navigate anywhere.
React Navigation的诞生,源于React Native社区对基于Javascript的可扩展且使用简单的导航解决方案的需求。
React Navigation是Facebook,Expo和React社区的开发者们合作的结果:它取代并改进了React Native生态系统中的多个导航库,其中包括Ex-Navigation,React Native的Navigator和NavigationExperimental组件。
内置导航器
react-navigation包含以下功能来帮助你创建导航器:
- StackNavigator - 一次只渲染一个页面,并提供页面之间跳转的方法。 当打开一个新的页面时,它被放置在堆栈的顶部
- TabNavigator - 渲染一个选项卡,让用户可以在几个页面之间切换
- DrawerNavigator - 提供一个从屏幕左侧滑入的抽屉
使用导航顶层组件
导航器渲染的仅仅是React组件对应的应用页面。
要了解如何创建页面,请阅读以下内容:
- Screen navigation prop 允许调用调用导航操作,例如打开另一个页面
- Screen navigationOptions 定制导航器显示如何显示(例如标题栏的标题,选项卡的标签)
二、使用
使用步骤如下:
- 导入依赖库
在项目Terminal中输入命令行:
npm install react-navigation --save
然后在package.json文件中就可以看到,依赖库已经导入完毕:
"react-native-tab-navigator": "^0.3.4",
接下来就可以愉快地使用react-navigation来进行页面导航了。
- 配置Navigator
- 在项目的入口中直接配置StackNavigator,StackNavigator中注册所有需要跳转的界面,在这个项目中还有注册登录功能,在效果图中没有展示,这里不作探讨。首先是入口文件:
import React from 'react';
import {StackNavigator} from 'react-navigation';
import {TabNav} from "./RootPage";
import LoginPage from "./page/Login/loginPage";
import RegPage from "./page/Login/regPage";
import {FindAccountPage} from "./page/Login/findAccountPage"; // 路由导航
const App = StackNavigator({
Login: {screen: LoginPage}, // 登录页
Reg: {screen: RegPage}, // 注册页
FindAccount: {screen: FindAccountPage}, // 找回密码页
Main: {
screen: TabNav,
navigationOptions: ({navigation}) => ({
header: null
})
}
},
{
initialRouteName: 'Login',
headerMode: 'screen'
});
export default App;
const MyApp = createStackNavigator({
Home: {
screen: BottomTab,
navigationOptions: {
header: null
}
},
Detail,
Search,
Login
}, {
headerMode: 'screen',
// headerMode: 'none',
mode: 'modal',
navigationOptions: {
gesturesEnabled: false,
},
transitionConfig: () => ({
transitionSpec: {
duration: 300,
easing: Easing.out(Easing.poly(4)),
timing: Animated.timing,
},
screenInterpolator: sceneProps => {
const { layout, position, scene } = sceneProps;
const { index } = scene;
const width = layout.initWidth;
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [width, 0, 0],
});
const opacity = position.interpolate({
inputRange: [index - 1, index - 0.99, index],
outputRange: [0, 1, 1],
});
return { opacity, transform: [{ translateX }] };
},
}),
});
export default MyApp
上面可以注意到TabNav,也就是TabNavigator,是作为一个screen参数的值传入到StackNavigator中,在上面提到的navigationOptions的配置中,我们将header设置为null,也就是不要标题栏。
- 接着进入到配置TabNavigator的RootPage中:
import React from 'react';
import {TabNavigator} from 'react-navigation';
import HomePage from './page/Home/HomePage';
import FriendPage from './page/Friend/FriendPage';
import TaskPage from './page/Task/TaskPage';
import MinePage from './page/Mine/MinePage';
import DealPage from './page/Deal/DealPage';
export const TabNav = TabNavigator(
{
Home: {
screen: HomePage,
},
Task: {
screen: TaskPage,
},
Friend: {
screen: FriendPage,
},
Deal: {
screen: DealPage,
},
Mine: {
screen: MinePage,
}
},
{
tabBarOptions: {
//当前选中的tab bar的文本颜色和图标颜色
activeTintColor: '#4BC1D2',
//当前未选中的tab bar的文本颜色和图标颜色
inactiveTintColor: '#000',
//是否显示tab bar的图标,默认是false
showIcon: true,
//showLabel - 是否显示tab bar的文本,默认是true
showLabel: true,
//是否将文本转换为大小,默认是true
upperCaseLabel: false,
//material design中的波纹颜色(仅支持Android >= 5.0)
pressColor: '#788493',
//按下tab bar时的不透明度(仅支持iOS和Android < 5.0).
pressOpacity: 0.8,
//tab bar的样式
style: {
backgroundColor: '#fff',
paddingBottom: 1,
borderTopWidth: 0.2,
paddingTop:1,
borderTopColor: '#ccc',
},
//tab bar的文本样式
labelStyle: {
fontSize: 11,
margin: 1
},
//tab 页指示符的样式 (tab页下面的一条线).
indicatorStyle: {height: 0},
},
//tab bar的位置, 可选值: 'top' or 'bottom'
tabBarPosition: 'bottom',
//是否允许滑动切换tab页
swipeEnabled: true,
//是否在切换tab页时使用动画
animationEnabled: false,
//是否懒加载
lazy: true,
//返回按钮是否会导致tab切换到初始tab页? 如果是,则设置为initialRoute,否则为none。 缺省为initialRoute。
backBehavior: 'none',
});
const BottomTab = createBottomTabNavigator({
MovieList: {
screen: HotList,
navigationOptions: {
tabBarLabel: '热映',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-laptop" size={20} color={tintColor} />
),
},
},
Seek: {
screen: Seek,
navigationOptions: {
tabBarLabel: '找片',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-eye" size={20} color={tintColor} />
),
},
},
Mine: {
screen: Mine,
navigationOptions: {
tabBarLabel: '我的',
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-person" size={20} color={tintColor} />
),
},
}
}, {
tabBarOptions: {
activeTintColor: '#494949',
inactiveTintColor: '#999999',
labelStyle: {
fontSize: 12,
marginBottom: 5,
},
style: {
borderTopWidth: 1,
borderTopColor: '#c3c3c3',
height: 50,
backgroundColor: '#fff'
},
}
});
- 在这个界面中导入了其他五个子界面,每个子界面效果可以设置成差不多,例如下面这样:
import React, {Component} from 'react';
import {
View,
Text,
Image,
StyleSheet,
} from 'react-native';
export default class FriendPage extends Component {
static navigationOptions = {
tabBarLabel: '好友',
tabBarIcon: ({focused}) => {
if (focused) {
return (
<Image style={styles.tabBarIcon} source={require('../../img/fri_sel.png')}/>
);
}
return (
<Image style={styles.tabBarIcon} source={require('../../img/fri_nor.png')}/>
);
},
};
render() {
return (
<View style={styles.container}>
<Text>这是好友</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
},
tabBarIcon: {
width: 21,
height: 21,
}
});
在子界面中可以设置icon图标样式,表示在点击前后颜色的改变,效果如下:
当然,我们也可以设置标题栏,只需要在下面代码中添加headerTitle属性:
export default class FriendPage extends Component {
static navigationOptions = {
tabBarLabel: '好友',
headerTitle: '好友',
tabBarIcon: ({focused}) => { ...
别忘了,在StackNavigator配置TabNavigator时不要设置header为null即可。
Main: {
screen: TabNav,
navigationOptions: ({navigation}) => ({
// header: null
})
}
关于DrawerNavigator,用到的情况比较少,就不展开说了,可以参考下面这个Demo 传送门