React-Native中导航组件react-navigation的使用
来源:互联网 发布:人工智能 龙头 编辑:程序博客网 时间:2024/05/21 05:21
写在开头的话
最近使用React-Native开发新应用,一开始使用的导航器是navigator,后来发现navigator有很多不足之处,而且官方也建议使用react-navigation来进行开发,所以现在转为使用react-navigation开发新应用了。
总览
React Native 中,官方已经推荐使用 react-navigation 来实现各个界面的跳转和不同板块的切换。react-navigation据称有原生般的性能体验效果。可能会成为未来React Native导航组件的主流军。该库主要有三个部分组成:
1、 StackNavigator: 类似于普通的Navigator,屏幕上方导航栏,用于实现各个页面之间的跳转
2、 TabNavigator: 相当于iOS里面的TabBarController,屏幕下方的标签栏,主要用于同一个页面上不同界面之间的切换
3、 DrawerNavigator: 抽屉效果,侧边滑出
StackNavigator 导航栏
StackNavigator 组件采用堆栈式的页面导航来实现各个界面跳转。
首先如果想要使用StackNavigator,一定要先注册导航。
const Navigator = StackNavigator( { Tab: { screen: Tab }, Web: { screen: WebScene }, GroupPurchase: { screen: GroupPurchaseScene }, }, { navigationOptions: { // headerStyle: { backgroundColor: color.theme } headerBackTitle: null, headerTintColor: '#333333', showIcon: true, }, });
这里配置了给导航器配置了三个界面,如果需要更多界面,可以在之后进行添加。主要有一个用于主界面之间能够切换的Tab界面和其他两个能够展示数据的界面。
StackNavigatorConfig 导航器的配置
- initialRouteName - 导航器组件中初始显示页面的路由名称,如果不设置,则默认第一个路由页面为初始显示页面
- initialRouteParams - 给初始路由的参数,在初始显示的页面中可以通过 this.props.navigation.state.params 来获取
- navigationOptions - 路由页面的配置选项,它会被 RouteConfigs 参数中的navigationOptions 的对应属性覆盖。
- paths - 路由中设置的路径的覆盖映射配置
mode - 页面跳转方式,有 card 和 modal 两种,默认为 card :
card - 原生系统默认的的跳转,左右互换
modal - 只针对iOS平台,模态跳转,上下切换headerMode - 页面跳转时,头部的动画模式,有 float 、 screen 、 none 三种:
float - 渐变,类似iOS的原生效果,无透明
screen - 标题与屏幕一起淡入淡出,如微信一样
none - 没有动画- cardStyle - 为各个页面设置统一的样式,比如背景色,字体大小等
- transitionConfig - 配置页面跳转的动画,覆盖默认的动画效果
- onTransitionStart - 页面跳转动画即将开始时调用
- onTransitionEnd - 页面跳转动画一旦完成会马上调用
代码示例:
const StackNavigatorConfig = { initialRouteName: 'Home', initialRouteParams: {initPara: '初始页面参数'}, navigationOptions: { title: '标题', headerTitleStyle: {fontSize: 18, color: '#666666'}, headerStyle: {height: 48, backgroundColor: '#'}, }, paths: 'page/main', mode: 'card', headerMode: 'screen', cardStyle: {backgroundColor: "#ffffff"}, transitionConfig: (() => ({ screenInterpolator: CardStackStyleInterpolator.forHorizontal, })), onTransitionStart: (() => { console.log('页面跳转动画开始'); }), onTransitionEnd: (() => { console.log('页面跳转动画结束'); }),};
navigationOptions 为对应路由页面的配置选项
- title - 可以作为头部标题 headerTitle ,或者Tab标题 tabBarLabel
- header - 自定义的头部组件,使用该属性后系统的头部组件会消失,如果想在页面中自定义,可以设置为null,这样就不会出现页面中留有一个高度为64navigationBar的高度
- headerTitle - 头部的标题,即页面的标题
- headerBackTitle - 返回标题,默认为 title
- headerTruncatedBackTitle - 返回标题不能显示时(比如返回标题太长了)显示此标题,默认为 “Back”
- headerRight - 头部右边组件
- headerLeft - 头部左边组件
- headerStyle - 头部组件的样式
- headerTitleStyle - 头部标题的样式
- headerBackTitleStyle - 头部返回标题的样式
- headerTintColor - 头部颜色
- headerPressColorAndroid - Android 5.0 以上MD风格的波纹颜色
- gesturesEnabled - 否能侧滑返回, iOS 默认 true , Android 默认 false
使用示例
// 注册导航const Navs = StackNavigator({ Home: { screen: Tabs }, HomeTwo: { screen: HomeTwo, // 必须, 其他都是非必须 path:'app/homeTwo', 使用url导航时用到, 如 web app 和 Deep Linking navigationOptions: {} // 此处设置了, 会覆盖组件内的`static navigationOptions`设置. 具体参数详见下文 }, HomeThree: { screen: HomeThree }, HomeFour: { screen: HomeFour }}, { initialRouteName: 'Home', // 默认显示界面 navigationOptions: { // 屏幕导航的默认选项, 也可以在组件内用 static navigationOptions 设置(会覆盖此处的设置) header: { // 导航栏相关设置项 backTitle: '返回', // 左上角返回键文字 style: { backgroundColor: '#fff' }, titleStyle: { color: 'green' } }, cardStack: { gesturesEnabled: true } }, mode: 'card', // 页面切换模式, 左右是card(相当于iOS中的push效果), 上下是modal(相当于iOS中的modal效果) headerMode: 'screen', // 导航栏的显示模式, screen: 有渐变透明效果, float: 无透明效果, none: 隐藏导航栏 onTransitionStart: ()=>{ console.log('导航栏切换开始'); }, // 回调 onTransitionEnd: ()=>{ console.log('导航栏切换结束'); } // 回调});
当然页面配置选项 navigationOptions 还可以在对应页面中去静态配置。
// 配置页面导航选项 static navigationOptions = ({navigation}) => ({ title: 'HOME', titleStyle: {color: '#ff00ff'}, headerStyle:{backgroundColor:'#000000'} }); render() { return ( <View></View> ) };}
在页面里面采用静态的方式配置 navigationOptions 中的属性,会覆盖 StackNavigator 构造函数中两个参数 RouteConfigs 和 StackNavigatorConfig 配置的 navigationOptions 里面的对应属性。 navigationOptions 中属性的优先级是:
页面中静态配置 > RouteConfigs > StackNavigatorConfig
我们可以在组件中直接使用该配置了,当然我们也可以像文章开头提过的那样使用:
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig);export default class Main extends Component { render() { return ( <Navigator/> ) };}
好了,我们到此已经配置好导航器和对应的路由页面了,但是我们还需要navigation才能实现页面的跳转。
navigation 控制页面跳转
在导航器中的每一个页面,都有 navigation 属性,该属性有以下几个属性/方法,可以在组件下console.log一下this.props就能看到。
- navigate - 跳转到其他页面
- state - 当前页面导航器的状态
- setParams - 更改路由的参数
- goBack - 返回
- dispatch - 发送一个action
navigate
this.props.navigation.navigate(‘Two’, { name: ‘two’ }): push下一个页面
◦ routeName: 注册过的目标路由名称◦ params: 传递的参数,传递到下一级界面◦ action: 如果该界面是一个navigator的话,将运行这个sub-action
state
state 里面包含有传递过来的参数 params、key 、路由名称 routeName
◦ routeName: 路由名◦ key: 路由身份标识◦ params: 参数
setParams
this.props.navigation.setParams: 该方法允许界面更改router中的参数,可以用来动态的更改导航栏的内容。比如可以用来更新头部的按钮或者标题。
goBack
返回上一页,可以不传参数,也可以传参数,还可以传 null 。
this.props.navigation.goBack(); // 回退到上一个页面this.props.navigation.goBack(null); // 回退到任意一个页面this.props.navigation.goBack('Home'); // 回退到Home页面
dispatch
this.props.navigation.dispatch: 可以dispatch一些action,主要支持的action有:
- 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)
- Reset: Reset方法会清除原来的路由记录,添加上新设置的路由信息, 可以指定多个action,index是指定默认显示的那个路由页面, 注意不要越界了
import { NavigationActions } from 'react-navigation' const resetAction = NavigationActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Profile'}), NavigationActions.navigate({ routeName: 'Two'}) ] }) 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)
页面跳转,传值,回调传参
跳转,传值
const {navigate} = this.props.navigation; <TouchableHighlight onPress={()=>{ navigate('PlanDetail',{name:'leslie',id:100}); }}> // 返回上一页 this.props.navigation.goBack();
在下一界面接收参数
通过 this.props.navigation.state.params 接收参数
export default class Home1 extends Component { static navigationOptions = { // title 可以这样设置成一个函数, state 会自动传过来 title: ({state}) => `${state.params.name}`, }; componentDidMount() { const {params} = this.props.navigation.state; const id = params.id; } }
回调传参
当前界面进行跳转
navigate('Detail',{ // 跳转的时候携带一个参数去下个页面 callback: (data)=>{ console.log(data); // 打印值为:'回调参数' } });
下一界面在返回之前传参
const {navigate,goBack,state} = this.props.navigation;// 在第二个页面,在goBack之前,将上个页面的方法取到,并回传参数,这样回传的参数会重走render方法state.params.callback('回调参数');goBack();
TabNavigator 即是Tab选项卡
TabNavigator(RouteConfigs, TabNavigatorConfig)
api和 StackNavigator 类似,参数 RouteConfigs 是路由配置,参数 TabNavigatorConfig是Tab选项卡配置。
RouteConfigs 路由配置
路由配置和 StackNavigator 中是一样的,配置路由以及对应的 screen 页面,navigationOptions 为对应路由页面的配置选项:
- title - Tab标题,可用作headerTitle 和 tabBarLabel 回退标题
- tabBarVisible - Tab的是否可见,没有设置的话默认为 true
- tabBarIcon - Tab的icon组件,可以根据 {focused: boolean, tintColor: string} 方法来返回一个icon组件
- tabBarLabel - Tab中显示的标题字符串或者组件,也可以根据 { focused: boolean, tintColor: string } 方法返回一个组件
代码示例:
Mine: { screen: MineScene, navigationOptions: ({ navigation }) => ({ tabBarLabel: '我的', tabBarIcon: ({ focused, tintColor }) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_mine@2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_mine_selected@2x.png')} /> ) }), },
TabBarItem自定义组件
class TabBarItem extends PureComponent { render() { let selectedImage = this.props.selectedImage ? this.props.selectedImage : this.props.normalImage return ( <Image source={this.props.focused ? selectedImage : this.props.normalImage} style={{ tintColor: this.props.tintColor, width: 25, height: 25 }} /> ); }}
TabNavigatorConfig Tab选项卡配置
tabBarComponent - Tab选项卡组件,有 TabBarBottom 和 TabBarTop 两个值,在iOS中默认为 TabBarBottom ,在Android中默认为 TabBarTop 。
TabBarTop - 在页面的顶部
TabBarBottom - 在页面的底部- tabBarPosition - Tab选项卡的位置,有top或bottom两个值
top:上面
bottom:下面 - swipeEnabled - 是否可以滑动切换Tab选项卡
- animationEnabled - 点击Tab选项卡切换界面是否需要动画
- lazy - 是否懒加载页面
- initialRouteName - 初始显示的Tab对应的页面路由名称
- order - 用路由名称数组来表示Tab选项卡的顺序,默认为路由配置顺序
- paths - 路径配置
backBehavior - androd点击返回键时的处理,有 initialRoute 和 none 两个值
initailRoute - 返回初始界面
none - 退出tabBarOptions - Tab配置属性,用在TabBarTop和TabBarBottom时有些属性不一致:
用于 TabBarTop 时:
- activeTintColor - 选中的文字颜色
- inactiveTintColor - 未选中的文字颜色
- showIcon - 是否显示图标,默认显示
- showLabel - 是否显示标签,默认显示
- upperCaseLabel - 是否使用大写字母,默认使用
- pressColor - android 5.0以上的MD风格波纹颜色
- pressOpacity - android 5.0以下或者iOS按下的透明度
- scrollEnabled - 是否可以滚动
- tabStyle - 单个Tab的样式
- indicatorStyle - 指示器的样式
- labelStyle - 标签的样式
- iconStyle - icon的样式
- style - 整个TabBar的样式
用于 TabBarBottom 时:
- activeTintColor - 选中Tab的文字颜色
- inactiveTintColor - 未选中Tab的的文字颜色
- activeBackgroundColor - 选中Tab的背景颜色
- inactiveBackgroundColor - 未选中Tab的背景颜色
- showLabel - 是否显示标题,默认显示
- style - 整个TabBar的样式
- labelStyle - 标签的样式
- tabStyle - 单个Tab的样式
使用底部选项卡:
import React, {Component} from 'react';import {StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";import HomeScreen from "./index18/HomeScreen";import NearByScreen from "./index18/NearByScreen";import MineScreen from "./index18/MineScreen";import TabBarItem from "./index18/TabBarItem";export default class MainComponent extends Component { render() { return ( <Navigator/> ); }}const TabRouteConfigs = { Home: { screen: HomeScreen, navigationOptions: ({navigation}) => ({ tabBarLabel: '首页', tabBarIcon: ({focused, tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_homepage_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_homepage_selected_2x.png')} /> ), }), }, NearBy: { screen: NearByScreen, navigationOptions: { tabBarLabel: '附近', tabBarIcon: ({focused, tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_merchant_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_merchant_selected_2x.png')} /> ), }, } , Mine: { screen: MineScreen, navigationOptions: { tabBarLabel: '我的', tabBarIcon: ({focused, tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_mine_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_mine_selected_2x.png')} /> ), }, }};const TabNavigatorConfigs = { initialRouteName: 'Home', tabBarComponent: TabBarBottom, tabBarPosition: 'bottom', lazy: true,};const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);const StackRouteConfigs = { Tab: { screen: Tab, }};const StackNavigatorConfigs = { initialRouteName: 'Tab', navigationOptions: { title: '标题', headerStyle: {backgroundColor: '#5da8ff'}, headerTitleStyle: {color: '#333333'}, }};const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
使用顶部选项卡:
import React, {Component} from "react";import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";import HomeScreen from "./index18/HomeScreen";import NearByScreen from "./index18/NearByScreen";import MineScreen from "./index18/MineScreen";export default class MainComponent extends Component { render() { return ( <Navigator/> ); }}const TabRouteConfigs = { Home: { screen: HomeScreen, navigationOptions: ({navigation}) => ({ tabBarLabel: '首页', }), }, NearBy: { screen: NearByScreen, navigationOptions: { tabBarLabel: '附近', }, } , Mine: { screen: MineScreen, navigationOptions: { tabBarLabel: '我的', }, }};const TabNavigatorConfigs = { initialRouteName: 'Home', tabBarComponent: TabBarTop, tabBarPosition: 'top', lazy: true, tabBarOptions: {}};const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);const StackRouteConfigs = { Tab: { screen: Tab, }};const StackNavigatorConfigs = { initialRouteName: 'Tab', navigationOptions: { title: '标题', headerStyle: {backgroundColor: '#5da8ff'}, headerTitleStyle: {color: '#333333'}, }};const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
DrawerNavigator 抽屉导航
有一些APP都会采用侧滑抽屉来做主页面的导航,利用 DrawerNavigator 在RN中可以很方便来实现抽屉导航。
DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)
和TabNavigator的构造函数一样,参数配置也类似
RouteConfigs
抽屉导航的路由配置 RouteConfigs ,和 TabNavigator 的路由配置完全一样, screen 配置对应路由页面, navigationOptions 为对应页面的抽屉配置选项:
- title - 抽屉标题,和 headerTitle 、 drawerLabel 一样
- drawerLabel - 标签字符串,或者自定义组件, 可以根据 { focused: boolean, tintColor: string } 函数来返回一个自定义组件作为标签
- drawerIcon - 抽屉icon,可以根据 { focused: boolean, tintColor: string } 函数来返回一个自定义组件作为icon
DrawerNavigatorConfig 属性配置
- drawerWidth - 抽屉宽度,可以使用Dimensions获取屏幕的宽度,动态计算
- drawerPosition - 抽屉位置,可以是 left 或者 right
- contentComponent - 抽屉内容组件,可以自定义侧滑抽屉中的所有内容,默认为 DrawerItems
- contentOptions - 用来配置抽屉内容的属性。当用来配置 DrawerItems 是配置属性选项:
- items - 抽屉栏目的路由名称数组,可以被修改
- activeItemKey - 当前选中页面的key id
- activeTintColor - 选中条目状态的文字颜色
- activeBackgroundColor - 选中条目的背景色
- inactiveTintColor - 未选中条目状态的文字颜色
- inactiveBackgroundColor - 未选中条目的背景色
- onItemPress(route) - 条目按下时会调用此方法
- style - 抽屉内容的样式
- labelStyle - 抽屉的条目标题/标签样式
- initialRouteName - 初始化展示的页面路由名称
- order - 抽屉导航栏目顺序,用路由名称数组表示
- paths - 路径
- backBehavior - androd点击返回键时的处理,有initialRoute和none两个值,initailRoute:返回初始界面, none :退出
抽屉导航示例:
import React, {Component} from 'react';import {DrawerNavigator, StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";import HomeScreen from "./index18/HomeScreen";import NearByScreen from "./index18/NearByScreen";import MineScreen from "./index18/MineScreen";import TabBarItem from "./index18/TabBarItem";export default class MainComponent extends Component { render() { return ( <Navigator/> ); }}const DrawerRouteConfigs = { Home: { screen: HomeScreen, navigationOptions: ({navigation}) => ({ drawerLabel : '首页', drawerIcon : ({focused, tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_homepage_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_homepage_selected_2x.png')} /> ), }), }, NearBy: { screen: NearByScreen, navigationOptions: { drawerLabel : '附近', drawerIcon : ({focused, tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_merchant_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_merchant_selected_2x.png')} /> ), }, }, Mine: { screen: MineScreen, navigationOptions: { drawerLabel : '我的', drawerIcon : ({focused, tintColor}) => ( <TabBarItem tintColor={tintColor} focused={focused} normalImage={require('./img/tabbar/pfb_tabbar_mine_2x.png')} selectedImage={require('./img/tabbar/pfb_tabbar_mine_selected_2x.png')} /> ), }, }};const DrawerNavigatorConfigs = { initialRouteName: 'Home', tabBarComponent: TabBarBottom, tabBarPosition: 'bottom', lazy: true, tabBarOptions: {}};const Drawer = DrawerNavigator(DrawerRouteConfigs, DrawerNavigatorConfigs);const StackRouteConfigs = { Drawer: { screen: Drawer, }};const StackNavigatorConfigs = { initialRouteName: 'Drawer', navigationOptions: { title: '标题', headerStyle: {backgroundColor: '#5da8ff'}, headerTitleStyle: {color: '#333333'}, }};const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
扩展功能
- 默认DrawerView不可滚动。要实现可滚动视图,必须使用contentComponent自定义容器
{ drawerWidth:200, 抽屉位置:“对” contentComponent:props => <ScrollView> <DrawerItems {... props}></DrawerItems> </ ScrollView> }
- 可以覆盖导航使用的默认组件,使用DrawerItems自定义导航组件
import {DrawerItems} from 'react-navigation'; const CustomDrawerContentComponent = (props) => ( <View style = {style.container}> <DrawerItems {... props} /> </View> );
- 嵌套抽屉导航
如果您嵌套DrawerNavigation,抽屉将显示在父导航下方。
自定义react-navigation
- 适配顶部导航栏标题
测试中发现,在iphone上标题栏的标题为居中状态,而在Android上则是居左对齐。所以需要我们修改源码,进行适配。
【node_modules – react-navigation – src – views – Header.js】的326行代码处,修改为如下:
title: { bottom: 0, left: TITLE_OFFSET, right: TITLE_OFFSET, top: 0, position: 'absolute', alignItems: 'center', }
上面方法通过修改源码的方式其实略有弊端,毕竟扩展性不好。还有另外一种方式就是,在navigationOptions中设置headerTitleStyle的alignSelf为 ’ center ‘即可解决。
* 去除返回键文字显示
【node_modules – react-navigation – src – views – HeaderBackButton.js】的91行代码处,修改为如下即可。
{ Platform.OS === 'ios' && title && <Text onLayout={this._onTextLayout} style={[styles.title, { color: tintColor }]} numberOfLines={1} > {backButtonTitle} </Text> }
将上述代码删除即可。
- 动态设置头部按钮事件
当我们在头部设置左右按钮时,肯定避免不了要设置按钮的单击事件,但是此时会有一个问题,navigationOptions是被修饰为static类型的,所以我们在按钮的onPress的方法中不能直接通过this来调用Component中的方法。如何解决呢?在官方文档中,作者给出利用设置params的思想来动态设置头部标题。那么我们可以利用这种方式,将单击回调函数以参数的方式传递到params,然后在navigationOption中利用navigation来取出设置到onPress即可:
componentDidMount () { /** * 将单击回调函数作为参数传递 */ this.props.navigation.setParams({ switch: () => this.switchView() }); }
/** * 切换视图 */ switchView() { alert('切换') }
static navigationOptions = ({navigation,screenProps}) => ({ headerTitle: '企业服务', headerTitleStyle: CommonStyles.headerTitleStyle, headerRight: ( <NavigatorItem icon={ Images.ic_navigator } onPress={ ()=> navigation.state.params.switch() }/> ), headerStyle: CommonStyles.headerStyle });
结合BackHandler处理返回和点击返回键两次退出App效果
点击返回键两次退出App效果的需求屡见不鲜。相信很多人在react-navigation下实现该功能都遇到了很多问题,例如,其他界面不能返回。也就是手机本身返回事件在react-navigation之前拦截了。如何结合react-natigation实现呢?和大家分享两种实现方式:(1)在注册StackNavigator的界面中,注册BackHandler
componentWillMount(){ BackHandler.addEventListener('hardwareBackPress', this._onBackAndroid ); } componentUnWillMount(){ BackHandler.addEventListener('hardwareBackPress', this._onBackAndroid); } _onBackAndroid=()=>{ let now = new Date().getTime(); if(now - lastBackPressed < 2500) { return false; } lastBackPressed = now; ToastAndroid.show('再点击一次退出应用',ToastAndroid.SHORT); return true; }
(2)监听react-navigation的Router
/** * 处理安卓返回键 */ const defaultStateAction = AppNavigator.router.getStateForAction; AppNavigator.router.getStateForAction = (action,state) => { if(state && action.type === NavigationActions.BACK && state.routes.length === 1) { if (lastBackPressed + 2000 < Date.now()) { ToastAndroid.show(Constant.hint_exit,ToastAndroid.SHORT); lastBackPressed = Date.now(); const routes = [...state.routes]; return { ...state, ...state.routes, index: routes.length - 1, }; } } return defaultStateAction(action,state); };
- 实现Android中界面跳转左右切换动画
react-navigation在android中默认的界面切换动画是上下。如何实现左右切换呢?很简单的配置即可:
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
然后在StackNavigator的配置下添加如下代码:
transitionConfig:()=>({ screenInterpolator: CardStackStyleInterpolator.forHorizontal, })
- 解决快速点击多次跳转
当我们快速点击跳转时,会开启多个重复的界面,如何解决呢。其实在官方Git中也有提示,解决这个问题需要修改react-navigation源码:
找到scr文件夹中的addNavigationHelpers.js文件,替换为如下文本即可:
export default function<S: *>(navigation: NavigationProp<S, NavigationAction>) { // 添加点击判断 let debounce = true; return { ...navigation, goBack: (key?: ?string): boolean => navigation.dispatch( NavigationActions.back({ key: key === undefined ? navigation.state.key : key, }), ), navigate: (routeName: string, params?: NavigationParams, action?: NavigationAction,): boolean => { if (debounce) { debounce = false; navigation.dispatch( NavigationActions.navigate({ routeName, params, action, }), ); setTimeout( () => { debounce = true; }, 500, ); return true; } return false; }, /** * For updating current route params. For example the nav bar title and * buttons are based on the route params. * This means `setParams` can be used to update nav bar for example. */ setParams: (params: NavigationParams): boolean => navigation.dispatch( NavigationActions.setParams({ params, key: navigation.state.key, }), ), }; }
欢迎关注我的公众号,一起交流学习!
- React-Native中导航组件react-navigation的使用
- React Native 页面跳转react-navigation导航器的使用
- react-native新导航组件react-navigation详解
- react-native新导航组件react-navigation详解
- react-native新导航组件react-navigation详解
- react-native新导航组件react-navigation详解
- 【React Native开发】- React Navigation的使用
- React Native导航器之react-navigation使用
- React Native导航器之react-navigation使用
- React Native未来导航者:react-navigation 使用详解
- React Native未来导航者:react-navigation 使用详解
- react-native使用react-navigation进行页面跳转导航
- React Native导航器之react-navigation使用
- React Native未来导航者:react-navigation 使用详解
- React Native未来导航者:react-navigation 使用详解
- React Native导航器之react-navigation使用
- React Native未来导航者:react-navigation 使用详解
- 【转载】React Native未来导航者:react-navigation 使用详解
- python3编码问题(网络流数据写入到本地出错问题)
- kaldi学习第三天
- PyQt5的多线程
- html定义列表
- 高德地图实现定位
- React-Native中导航组件react-navigation的使用
- GPIO操作
- html的class和id
- 执行环境 & 作用域 & 闭包
- 自定义控件之 PasswordEditText(密码输入框)
- C/C++中volatile关键字详解
- 跨越编程语言界限(一)
- MyEclipse中将普通Java项目convert(转化)为Maven项目
- Constraint must contain a first layout item