react native从2017年在开发社区主推导航库react-navigation,而Navigator这个导航跳转的老组件会逐步被React Navigation替代,本文也是以react-navigation来实现启动页,然后跳转到三张引导页,最后跳转到带有抽屉效果的底部导航界面。本文并未对react-navigation中的屏幕上方导航栏StackNavigator,屏幕下方的标签TabNavigator,侧边滑出的抽屉效果DrawerNavigator中的属性做详细的介绍,需要基本了解这些属性及用法才能更容易看懂,不过即使不了解,本文也会让你了解这三个组件的基本用法,首先在文件index.android.js中导入import {StackNavigator} from 'react-navigation';将导航栏StackNavigator引入进来,然后构建启动页SplashComponent.js,引导页GuideComponent.js,带抽屉导航页AppComponent.js,文件中具体的代码稍后附上。
index.android.js文件中的代码如下:
import React, {Component} from 'react';
import {StackNavigator} from 'react-navigation';
import {
AppRegistry,
} from 'react-native';
import SplashComponent from './src/component/SplashComponent';
import GuideComponent from './src/component/GuideComponent';
import AppComponent from './src/component/AppComponent';
let Stack = StackNavigator({
Splash: {screen: SplashComponent},
Guide: {screen: GuideComponent},
Drawer: {screen: AppComponent},
},
{
initialRouteName: 'Splash',
mode: 'card',
headerMode: 'none',
});
/*这里必须是Stack,跳转其他组件如果有点击事件就会报跳转方法错误*/
AppRegistry.registerComponent('AwesomeProject', () => Stack);
这样构建之后,点击就可以跳转到启动页了,启动页做了3秒停留自动跳转引导页,同时做了动画渐变效果。
启动页SplashComponent.js中的代码:
import React, {Component}from 'react';
import {
StyleSheet,
View,
Image,
Animated,
Easing,
} from 'react-native';
/*组件必须export default修饰*/
export default class SplashComponent extends Component {
constructor(props) {
super(props);
this.state = {
fadeAnim: new Animated.Value(0), // 透明度初始值设为0
};
}
componentDidMount() {
Animated.timing( // 随时间变化而执行的动画类型
this.state.fadeAnim, // 动画中的变量值
{
toValue: 1,// 透明度最终变为1,即完全不透明
duration: 3000,
easing: Easing.bezier(0.15, 0.73, 0.37, 1.2) //缓动函数
}
).start();
// 开始执行动画
setTimeout(() => {
this.props.navigation.navigate('Guide');
}, 3000);
}
render() {
return (
);
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
content: {
justifyContent: 'center',
backgroundColor: 'yellow',
},
button: {
marginTop: 10,
paddingVertical: 10,
paddingHorizontal: 20,
backgroundColor: 'black'
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
}
});
这样做了以后,3秒后就会自动跳转到引导页,
引导页GuideComponent.js组建中的代码:
import React, {Component}from 'react';
import {
StyleSheet,
View,
Image,
Text,
ViewPagerAndroid,
} from 'react-native';
export default class GuideComponent extends Component {
render() {
const {navigate} = this.props.navigation;
return (
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
guideImage: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
width: 400,
height: 650
},
guideT: {
textAlign: 'center',
paddingTop: 10,
marginTop: 450,
color: 'red',
fontSize: 20,
height: 45,
width: 150,
backgroundColor: '#ffffff',
borderRadius: 20,
borderWidth: 2,
borderColor: 'red',
},
引导过后,点击立即体验,通过点击监听事件onPress={() => this.props.navigation.navigate('Drawer')}跳转到主界面AppComponent
AppComponent.js主要引用了TabNavigator, TabBarBottom, DrawerNavigator来实现抽屉效果,底部标签,不过要想从抽屉界面的“个人中心”“设置”’、底部导航界面中的“首页”,“发现”,“精选”,“我的”界面跳转到新的界面,再像原来把新建的组件引入到index.android.js下面的像
let Stack = StackNavigator({
Splash: {screen: SplashComponent},
Guide: {screen: GuideComponent},
Drawer: {screen: AppComponent},
Login:: {screen: LoginComponent},
},
LoginComponent.js既不在抽屉界面,也不在底部导航界面,就无法实现跳转到LoginComponent界面,还需要在AppComponent.js中引入StackNavigator,将新的组件比如LoginComponent放入其中,稍后看具体的代码如何实现,而已经在index.android.js中的StackNavigator和AppComponent.js中的DrawerNavigator、TabNavigator放入的组件就不需要重新放了,其他组件就可以跳转进来。
TabBarItem是自定义的底部导航标签组件,代码如下:
import React,{Component} from 'react';
import {Image} from 'react-native';
export default class TabBarItem extends Component {
render() {
return(
/>
)
}
}
像其他组件:HomeComponent.js,MyComponent.js等组件自己随意创建就可以。
另外重要的我做的是将TabNavigator放入到DrawerNavigator,然后将DrawerNavigator放入到StackNavigator
AppComponent.js代码如下:
import {
StyleSheet,
AppRegistry,
Text,
View,
Image,
ToastAndroid
} from 'react-native';
import {StackNavigator, TabNavigator, TabBarBottom, DrawerNavigator} from 'react-navigation';
import HomeComponent from './HomeComponent.js';
import DiscoverComponent from './DiscoverComponent.js';
import MyComponent from './MyComponent.js';
import TabBarItem from './TabBarItem.js';
import UserComponent from './UserComponent.js';
import SetComponent from './SetComponent.js';
import ChoiceComponent from './ChoiceComponent.js';
import CartoonDetailsComponent from './CartoonDetailsComponent';
import LoginComponent from './LoginComponent';
import EditorUserComponent from './EditorUserComponent';
export default class AppComponent extends Component {
render() {
return (
);
}
}
const Tab = TabNavigator(
{
Home: {
screen: HomeComponent,
navigationOptions: ({navigation}) => ({
tabBarLabel: '首页',
header: null,
tabBarIcon: ({focused, tintColor}) => (
focused={focused}
normalImage={require('./../image/menu_bottom/car.png')}
selectedImage={require('./../image/menu_bottom/car_hover.png')}
/>
)
}),
},
TabHorizon: {
screen: DiscoverComponent,
navigationOptions: ({navigation}) => ({
tabBarLabel: '发现',
header: null,
tabBarIcon: ({focused, tintColor}) => (
focused={focused}
normalImage={require('./../image/menu_bottom/card.png')}
selectedImage={require('./../image/menu_bottom/card_hover.png')}
/>
)
}),
},
Choice: {
screen: ChoiceComponent,
navigationOptions: ({navigation}) => ({
tabBarLabel: '精选',
header: null,
tabBarIcon: ({focused, tintColor}) => (
focused={focused}
normalImage={require('./../image/like.png')}
selectedImage={require('./../image/like_hover.png')}
/>
)
}),
},
Mine: {
screen: MyComponent,
navigationOptions: ({navigation}) => ({
tabBarLabel: '我的',
header: null,
tabBarIcon: ({focused, tintColor}) => (
focused={focused}
normalImage={require('./../image/title_user.png')}
selectedImage={require('./../image/title_user_hover.png')}
/>
)
}),
},
},
{
initialRouteName: 'Home',
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',// 设置tabbar的位置,iOS默认在底部,安卓默认在顶部。(属性值:'top','bottom')
swipeEnabled: false, // 是否可以左右滑动切换tab
animationEnabled: true,// 切换页面时是否有动画效果
backBehavior: 'none', // 按 back 键是否跳转到第一个Tab(首页), none 为不跳转
lazy: true,//是否根据需要懒惰呈现标签,而不是提前,意思是在app打开的时候将底部标签栏全部加载,默认false,推荐为true
header: null,
tabBarOptions: {
activeTintColor: '#21baef', // 文字和图片选中颜色
inactiveTintColor: '#232519', // 文字和图片未选中颜色
showIcon: true, // android 默认不显示 icon, 需要设置为 true 才会显示
showLabel: true,//是否显示label,默认开启 style:tabbar的样式
style: {backgroundColor: '#ffffff',},
indicatorStyle: {
height: 0 // 如TabBar下面显示有一条线,可以设高度为0后隐藏
},
labelStyle: { // 文字标签样式
fontSize: 12,
},
iconStyle: {},//图标样式
}
}
);
const Drawer = DrawerNavigator({
Tab: {
screen: Tab,
navigationOptions: ({navigation}) => ({
drawerLabel: '首页',
header: null,
drawerIcon: ({tintColor}) => (
style={{width: 25, height: 25}}
/* //style={[styles.icon, {tintColor: tintColor}]}*//>
),
}),
},
User: {
screen: UserComponent,
navigationOptions: ({navigation}) => ({
drawerLabel: '个人中心',
header: null,
drawerIcon: ({tintColor}) => (
style={{width: 25, height: 25}}
/* //style={[styles.icon, {tintColor: tintColor}]}*//>
),
}),
},
Set: {
screen: SetComponent,
navigationOptions: ({navigation}) => ({
drawerLabel: '设置',
header: null,
drawerIcon: ({tintColor}) => (
style={{width: 25, height: 25}}
/>
),
}),
},
},
{
drawerWidth: 260,
drawerPosition: 'left',
header: null,
//配置抽屉内容
contentOptions: {
initialRouteName: 'Tab', // 默认页面组件
activeTintColor: 'blue', // 选中文字颜色
inactiveTintColor: '#232528', // 未选中文字颜色
activeBackgroundColor: '#bababa', // 选中背景颜色
inactiveBackgroundColor: '#fff', // 未选中背景颜色
style: { // 样式
margin: 0,
},
/* labelStyle: {//文本标签样式,当标签是字符串时,就会覆盖contentOptions内容部分中设置的文本样式
color: 'red',
width:30,
},*/
},
}
);
let Stacks = StackNavigator({
Drawer:{screen: Drawer},
Cartoon:{screen: CartoonDetailsComponent},
Login:{screen: LoginComponent},
EditorUser:{screen: EditorUserComponent},
},
{
initialRouteName: 'Drawer',
mode: 'card',
headerMode: 'none',
},
);