React Native导航器之react-navigation使用
在上一节Navigation组件,我们使用系统提供的导航组件做了一个跳转的例子,不过其实战能力不强,这里推荐一个超牛逼的第三方库:react-navigation。在讲react-navigation之前,我们先看一下常用的导航组件。 导航控件常见的导航主要分为三种: Navigation 使用在你使用navigation的每一个界面navigation都提供相关的属性和响应方法,常见的有: 例如: class HomeScreen extends React.Component {
render() {
const {navigate} = this.props.navigation;
return (
<View>
<Text>This is the home screen of the app</Text>
<Button
onPress={() => navigate('Profile',{name: 'Brent'})}
title="点击我跳转"
/>
</View>
)
}
}
state当前路由状态 每个界面通过this.props.navigation.state去访问它的router,state其中包括了: Navigate使用例如: import { NavigationActions } from 'react-navigation'
const navigationAction = NavigationActions.navigate({
routeName: 'Profile',params: {},// navigate can have a nested navigate action that will be run inside the child router
action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigationAction)
ResetReset方法会擦除掉所有的导航状态,并且使用新的结果替代。 import { NavigationActions } from 'react-navigation'
const resetAction = NavigationActions.reset({
index: 0,actions: [
NavigationActions.navigate({ routeName: 'Profile'})
]
})
this.props.navigation.dispatch(resetAction)
SetParams为指定的router更新参数,该参数必须是已经存在于router的param中。 import { NavigationActions } from 'react-navigation'
const setParamsAction = NavigationActions.setParams({
params: {},// these are the new params that will be merged into the existing route params
// The key of the route that should get the new params
key: 'screen-123',})
this.props.navigation.dispatch(setParamsAction)
StackNavigator使用StackNavigator使用比较简单,看一个常见的例子: class MyHomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',//设置navigator的title
}
render() {
return (
//button的onPress方法,实现点击跳转界面,并且传递参数name:Lucy
<Button
onPress={() => this.props.navigation.navigate('Profile',{name: 'Lucy'})}
title="Go to Lucy's profile"
/>
);
}
}
//生成路由关系
const ModalStack = StackNavigator({
Home: {
//对应界面MyHomeScreen
screen: MyHomeScreen,},Profile: {
path: 'people/:name',screen: MyProfileScreen,});
StackNavigatorConfigoption for the route(路由选项):·initialRouteName -为stack设置默认的界面,必须和route configs里面的一个key匹配。 Visual Option(视觉选项):·mode- 定义渲染(rendering)和转换(transitions)的模式,两种选项: ·headerMode- 指定header应该如何被渲染,选项: ·cardStyle- 使用该属性继承或者重载一个在stack中的card的样式。 Navigation Options你还可以定义一个静态的navigationOptions在你的组件之上。 lass ProfileScreen extends React.Component {
//设置navigation选项
static navigationOptions = {
//标题
title: ({ state }) => `${state.params.name}'s Profile!`,//头部定义了一个右按钮,来改变edit的状态 ing或者完成
header: ({ state,setParams }) => ({
// Render a button on the right side of the header
// When pressed switches the screen to edit mode.
right: (
<Button
title={state.params.editing ? 'Done' : 'Edit'}
onPress={() => setParams({editing: state.params.editing ? false : true})}
/>
),}),};
...
常用的配置中,主要有以下参数需要注意: react-navigation说完常见的导航器,我们在看看本文的重点:react-navigation的使用。 1,在项目目录下,安装React-navigation库 npm install --save react-navigation
2,使用StactkNavigator来管理堆栈。暂且命名为HomeScreen.js。默认入口页面代码如下: import React from 'react';
import {
AppRegistry,Text,} from 'react-native';
//导入stack导航组件
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',//标题
};
render() {
return <Text>Hello,Navigation!</Text>;
}
}
//导航注册
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },});
AppRegistry.registerComponent('SimpleApp',() => SimpleApp);
运行效果: 3,添加一个新的页面 class ChatScreen extends React.Component {
static navigationOptions = {
title: 'Chat with Lucy',};
render() {
return (
<View>
<Text>Chat with Lucy</Text>
</View>
);
}
}
4,在HomeScreen中添加一个button组件,使用routeName Chat关联到ChatScreen。 class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello,Chat App!</Text>
<Button
onPress={() => navigate('Chat')}
title="Chat with Lucy"
/>
</View>
);
}
}
这段代码主要是给Button绑定onPress事件。这时候,我们使用的两个跳转的页面需要在StackNavigator进行注册: const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },Chat: { screen: ChatScreen },//新添加的页面
});
所以完整的代码是: class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',//设置标题内容
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello,Navigation!</Text>
<Button
onPress={() => navigate('Chat',{user:'Lucy'})}
title="Chat with Lucy"/>
</View>
);
}
}
const SimpleApp = StackNavigator({
Home: {screen: HomeScreen},Chat:{screen:ChatScreen},});
参数传递在页面的跳转过程中,往往会伴随着参数的传递。 navigation参数传递1,在第一个页面定义参数,将参数传值给需要传值的页面 constructor(props) { super(props); this.state = {};
}
...
if(navigator) { navigator.push({ name: 'SecondPageComponent',component: SecondPageComponent,params:{ user:this.state.user,pwd:this.state.pwd }
})
}
2,如果需要监听页面的state状态 onChangeText={(text) => this.setState({user: text})}
3,另一个页面接受参数 componentDidMount() {
//这里获取从FirstPageComponent传递过来的参数: id
this.setState({
user:this.props.user,pwd:this.props.pwd
});
}
4,去的传过来的值: value={this.state.user }
react-navigation参数传递对于 react-navigation参数的传递,使用上比较简单,只需要在navigate中加一个json格式的对象即可,如: navigate('Chat',{ user: 'Lucy' })
然后在接受的页面: class ChatScreen extends React.Component {
static navigationOptions = {
// Nav options can be defined as a function of the navigation prop:
title: ({ state }) => `Chat with ${state.params.user}`,};
render() {
// The screen's current route is passed in to `props.navigation.state`:
const { params } = this.props.navigation.state;
return (
<View>
<Text>Chat with {params.user}</Text>
</View>
);
}
}
所以,你就可以看到如下的效果: TabNavigatorTabNavigator类似于底部导航效果 // 注册tabs
const Tabs = TabNavigator({
Home: {
screen: Home,navigationOptions: { // 也可以写在组件的static navigationOptions内
tabBar: {
label: '首页',icon: ({tintColor}) => (<Image source={require('./app/images/home.png')} style={[{tintColor: tintColor},styles.icon]}/>),}
},Bill: {
screen: Bill,navigationOptions: {
tabBar: {
label: '账单',icon: ({tintColor}) => (<Image source={require('./app/images/bill.png')} style={[{tintColor: tintColor},Me: {
screen: Me,navigationOptions: {
tabBar: {
label: '我',icon: ({tintColor}) => (<Image source={require('./app/images/me.png')} style={[{tintColor: tintColor},}
}
},{
animationEnabled: false,// 切换页面时是否有动画效果
tabBarPosition: 'bottom',// 显示在底端,android 默认是显示在页面顶端的
swipeEnabled: false,// 是否可以左右滑动切换tab
backBehavior: 'none',// 按 back 键是否跳转到第一个Tab(首页), none 为不跳转
tabBarOptions: {
activeTintColor: '#ff8500',// 文字和图片选中颜色
inactiveTintColor: '#999',// 文字和图片未选中颜色
showIcon: true,// android 默认不显示 icon,需要设置为 true 才会显示
indicatorStyle: {
height: 0 // 如TabBar下面显示有一条线,可以设高度为0后隐藏
},style: {
backgroundColor: '#fff',// TabBar 背景色
// height: 44
},labelStyle: {
fontSize: 10,// 文字大小
},});
DrawerNavigatorDrawerNavigator类似于抽屉侧滑效果。 const DrawerNav = DrawerNavigator({
Home: { screen: Home },Bill: { screen: Bill },Me: { screen: Me },HomeTwo: { screen: HomeTwo },HomeThree: { screen: HomeThree },HomeFour: { screen: HomeFour },BillTwo: { screen: BillTwo },BillThree: { screen: BillThree }
},{
drawerWidth: 200,// 抽屉宽
drawerPosition: 'left',// 抽屉在左边还是右边
// contentComponent: CustomDrawerContentComponent,// 自定义抽屉组件
contentOptions: {
initialRouteName: Home,// 默认页面组件
activeTintColor: 'white',// 选中文字颜色
activeBackgroundColor: '#ff8500',// 选中背景颜色
inactiveTintColor: '#666',// 未选中文字颜色
inactiveBackgroundColor: '#fff',// 未选中背景颜色
style: { // 样式
}
}
});
iOS版设置在iOS中使用react-navigation需要注意以下几点: - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
js组件在注册路由时设置唯一的路径path,例如Home2: { screen: Home2,path:’app/Home2’ }; react-native-tab-navigator直接上代码: /**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React,{ Component } from 'react';
import TabNavigator from 'react-native-tab-navigator';
import {
AppRegistry,StyleSheet,Image,View
} from 'react-native';
const TabNavigatorItem =TabNavigator.Item;
//默认选项
const TAB_HOME_NORMAL=require('./image/tabbar_homepage.png');
const TAB_MINE_NORMAL=require('./image/tabbar_mine.png');
//选中
const TAB_HOME_PRESS=require('./image/tabbar_homepage_selected.png');
const TAB_MINE_PRESS=require('./image/tabbar_mine_selected.png');
export default class HelloWord extends Component {
//默认选中
constructor(){
super();
this.state={
selectedTab:'Home',}
}
//点击方法
onPress(tabName){
if(tabName){
this.setState({
selectedTab:tabName,}
);
}
}
//渲染选项
renderTabView(title,tabName,tabContent,isBadge){
var tabNomal;
var tabPress;
switch (tabName) {
case 'Home':
tabNomal=TAB_HOME_NORMAL;
tabPress=TAB_HOME_PRESS;
break;
case 'Mine':
tabNomal=TAB_MINE_NORMAL;
tabPress=TAB_MINE_PRESS;
break;
default:
}
return(
<TabNavigatorItem
selected={this.state.selectedTab===tabName}
title={title}
titleStyle={styles.tabText}
selectedTitleStyle={styles.selectedTabText}
renderIcon={()=><Image style={styles.icon} source={tabNomal}/>}
renderSelectedIcon={()=><Image style={styles.icon} source={tabPress}/>}
onPress={()=>this.onPress(tabName)}
renderBadge={()=>isBadge?<View style={styles.badgeView}><Text style={styles.badgeText}>15</Text></View>:null}
>
<View style={styles.page}><Text>{tabContent}</Text></View>
</TabNavigatorItem>
);
}
//自定义TabView
tabBarView(){
return (
<TabNavigator
tabBarStyle={styles.tab}
>
{this.renderTabView('首页','Home','首页模块',true)}
{this.renderTabView('我的','Mine','我的模块',false)}
</TabNavigator>
);
}
//渲染界面
render() {
var tabView=this.tabBarView();
return (
<View style={styles.container}>
{tabView}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},tabText: {
fontSize: 10,color: 'black'
},selectedTabText: {
fontSize: 10,color: 'green'
},tab:{
height: 52,alignItems:'center',backgroundColor:'#f4f5f6',tabIcon:{
width:25,height:25,badgeView:{
width:22,height:14,backgroundColor:'#f85959',borderWidth:1,marginLeft:10,marginTop:3,borderColor:'#FFF',justifyContent:'center',borderRadius:8,badgeText:{
color:'#fff',fontSize:8,icon: {
width: 22,height: 22
},page: {
flex: 1,justifyContent: 'center',alignItems: 'center',backgroundColor: '#FFFFFF'
},});
AppRegistry.registerComponent('HelloWord',() => HelloWord);
参考:React Native页面参数传递 react-native-tab-navigator封装 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |