React-navigation之StackNavigator

1 先给出资料:

   官网: StackNavigator
   参考: 资料一资料二
有问题找  issues , 基本上坑都在这里。

2 导航栏分类

按使用形式主要分三部分:

(1) StackNavigator: 类似于普通的Navigator,实现不同的页面进行跳转
(2) TabNavigator: 相当于里面的TabBarController,屏幕上方的标签栏,不同的tabs互相切换。
(3) DrawerNavigator: 抽屉效果,侧边滑出

今天主要学习StackNavigator,另外两个随后跟上。

3  navigationOptions 

在这一块我是狠狠的被坑了一把,资料上给出的navigationOptions是这样的:

  • title: 导航栏的标题

  • header: 导航栏设置对象

    • visible: 导航栏是否显示
    • title: 导航栏的标题, 可以是字符串也可以是个组件
    • backTitle: 左上角的返回键文字, 默认是上一个页面的title
    • right: 导航栏右按钮
    • left: 导航栏左按钮
    • style: 导航栏的style
    • titleStyle: 导航栏的title的style
    • tintColor: 导航栏颜色
  • cardStack: 配置card stack

    • gesturesEnabled: 是否允许右滑返回,在iOS上默认为true,在Android上默认为false

      按照说明设置各种属性,结果是各种无效,查找资料也没有找到好的实例,好吧,还是回来看官方文档,哎,才发现navigationOptions变样了,可能是版本更新了或编辑器的问题的,在这里我用的编辑器是Sublime Text,反正是各种无效,我们来看官网的navigationOptions:

  • title: 导航栏的标题

  • header: 导航栏设置对象

  • headerTitle: 导航栏的标题, 可以是字符串也可以是个组件
  • headerBackTitle: 左上角的返回键文字, 默认是上一个页面的title,设置这个属性会覆盖掉title的值
  • headerRight: 导航栏右按钮
  • headerLeft: 导航栏左按钮
  • headerStyle: 导航栏的style
  • headerTitleStyle: 导航栏的title的style
  • headerTintColor: 返回按钮的颜色
  • headerPressColorAndroid :按压返回按钮显示的颜色 安卓系统 >= 5.0才有效。
  • gesturesEnabled :是否允许右滑返回,在iOS上默认为true,在Android上默认为false

使用事例:

ChatScreen.navigationOptions = ({navigation}) => {
	console.log("---------navigation------------>");
    console.log(navigation);
    //Object {state: Object, dispatch: function, goBack: function, navigate: function, setParams: function}
	return {
         // 展示数据 "`" 不是单引号 
         title: `Chat with ${navigation.state.params.user}`,
         // 导航栏的标题, 可以是字符串也可以是个组件 会覆盖 title 的值 
         // headerTitle : '返回',
         //右边按钮
         headerRight:(  
         	<View>
                <Button  
                   title="点我" 
                   onPress={() => alert("hello")}  
                />  
         	</View>   
        ),
         //左上角的返回键文字, 默认是上一个页面的title  IOS 有效
         headerBackTitle : "返回",
            //导航栏的style
         headerStyle: {
                backgroundColor: '#fff'
            },
            //导航栏的title的style
         headerTitleStyle: {
                color: 'green',
                //居中显示
                alignSelf : 'center',
         },
         //按压返回按钮显示的颜色 API > 5.0 有效
         headerPressColorAndroid : 'blue',
         //返回按钮的颜色
         headerTintColor : 'red',
         //是否允许右滑返回,在iOS上默认为true,在Android上默认为false
         gesturesEnabled: true,
	};
  	   
};

4  StackNavigatorConfig

参数:

  • initialRouteName: 设置默认的页面组件,必须是上面已注册的页面组件
  • initialRouteParams: 初始路由的参数
  • navigationOptions: 屏幕导航的默认选项
  • paths: RouteConfigs里面路径设置的映射

  • mode: 页面切换模式:

    • card: 普通app常用的左右切换
    • modal: 上下切换
  • headerMode: 导航栏的显示模式:

    • float: 无透明效果, 默认
    • screen: 有渐变透明效果, 如微信QQ的一样
    • none: 隐藏导航栏
  • cardStyle: 样式

  • onTransitionStart: 页面切换开始时的回调函数

  • onTransitionEnd: 页面切换结束时的回调函数

这个到没有什么变化。

5 API

StackNavigator(RouteConfigs, StackNavigatorConfig)

参数一:配置你需要跳转的导航界面,参数二:可选,配置属性(参见4)。

例:

// MyFirstProject 是你的react native 项目名  注意: 这块代码要放置到HomeScreen,ChatScreen...的下面否则会出错:Home不存在。
const MyFirstProject = StackNavigator({
  Home: { screen: HomeScreen },
  Chat: { screen: ChatScreen },
  // navigationOptions: {}  // 此处设置了, 会覆盖组件内的`static navigationOptions`设置. 
},{
	initialRouteName: 'Home', // 默认显示界面
	  //导航栏相关设置项
    // header:{
    // 	    //导航栏可见
    //         visible : false,
    //         //左上角的返回键文字, 默认是上一个页面的title
    //         backTitle : "返回",
    //         //导航栏的style
    //         headerStyle: {
    //             backgroundColor: '#fff'
    //         },
    //         //导航栏的title的style
    //         titleStyle: {
    //             color: 'green'
    //         }
    // },
    // title : 'home',
    // //导航栏的style
    //  headerStyle: {
    //             backgroundColor: '#fff'
    //  },
    //         //导航栏的title的style
    //  headerTitleStyle: {
    //          color: 'blue',
    //          //居中显示
    //          alignSelf : 'center',
    //      },

    // //是否允许右滑返回,在iOS上默认为true,在Android上默认为false
    // cardStack: {
    //         gesturesEnabled: true,
    // },
    onTransitionStart: ()=>{ console.log('导航栏切换开始'); },  // 回调
    onTransitionEnd: ()=>{ console.log('导航栏切换结束'); },  // 回调
});

6 数据传递分析

import React from 'react';
import {
  AppRegistry,
  Text,
  View,
  Button,
} from 'react-native';
import { StackNavigator } from 'react-navigation';


//第一个页面
class HomeScreen extends React.Component {
  // static navigationOptions = {
  // 	//标题
  //   title: 'FirstScreen',
  //    //是否允许右滑返回,在iOS上默认为true,在Android上默认为false
  //   cardStack: {
  //           gesturesEnabled: true,
  //   },

  // };

  render() {
  	const { navigate } = this.props.navigation;
  	// navigate 是什么鬼 就是下面的这块代码 可见 navigate 是个function对象 参数一 是要跳转的页面名字 例如:Chat 参数2:要传递的参数 参数3: 一般不用
  	// function navigate(routeName, params, action) {
   //    return navigation.dispatch(_NavigationActions2.default.navigate({
   //      routeName: routeName,
   //      params: params,
   //      action: action
   //    }));
  	console.log(navigate);
    return (
    	<View>
            <Text>Hello, Navigation!</Text>
            <Text></Text>
           <Button
              //点击跳转到界面二,并传递参数 { user: 'Lucy' }
              onPress={() => navigate('Chat', { user: 'Lucy' })}
              title="去 ChatScreen界面"
           />
           <Text></Text>
    	</View>
    );
  }
}

// // 这样也是可以
// HomeScreen.navigationOptions = {
//   	//标题
//     title: 'FirstScreen',
//      //是否允许右滑返回,在iOS上默认为true,在Android上默认为false
//     cardStack: {
//             gesturesEnabled: true,
//     },

//  };

// 第二个页面
class ChatScreen extends React.Component {

  static navigationOptions = ({navigation}) => ({
  	// 展示数据 "`" 不是单引号 
    title: `Chat with ${navigation.state.params.user}`,
    
  });

  render() {

  	// The screen's current route is passed in to `props.navigation.state`: 传过来的对象:{ user: 'Lucy' }
    const { params } = this.props.navigation.state;
    console.log(this.props.navigation);
    //object {state: Object, dispatch: function, goBack: function, navigate: function, setParams: function}
    console.log(this.props.navigation.state);
    //Object {params: Object, key: "id-1498014888408-1", routeName: "Chat"}
    console.log("-----------params----------->");
    console.log(params);
    //打印结果{user: "Lucy"}
    return (
      <View>
        <Text>Chat with {params.user}</Text>
      </View>
    );
  }
}

ChatScreen.navigationOptions = ({navigation}) => {
	console.log("---------navigation------------>");
    console.log(navigation);
    //Object {state: Object, dispatch: function, goBack: function, navigate: function, setParams: function}
	return {
         // 展示数据 "`" 不是单引号 
         title: `Chat with ${navigation.state.params.user}`,
         // 导航栏的标题, 可以是字符串也可以是个组件 会覆盖 title 的值 
         // headerTitle : '返回',
         //右边按钮
         headerRight:(  
         	<View>
                <Button  
                   title="点我" 
                   onPress={() => alert("hello")}  
                />  
         	</View>   
        ),
         //左上角的返回键文字, 默认是上一个页面的title  IOS 有效
         headerBackTitle : "返回",
            //导航栏的style
         headerStyle: {
                backgroundColor: '#fff'
            },
            //导航栏的title的style
         headerTitleStyle: {
                color: 'green',
                //居中显示
                alignSelf : 'center',
         },
         //按压返回按钮显示的颜色 API > 5.0 有效
         headerPressColorAndroid : 'blue',
         //返回按钮的颜色
         headerTintColor : 'red',
         //是否允许右滑返回,在iOS上默认为true,在Android上默认为false
         gesturesEnabled: true,
	};
  	   
};

// MyFirstProject 是你的react native 项目名  注意: 这块代码要放置到HomeScreen,ChatScreen...的下面否则会出错:Home不存在。
const MyFirstProject = StackNavigator({
  Home: { screen: HomeScreen },
  Chat: { screen: ChatScreen },
  // navigationOptions: {}  // 此处设置了, 会覆盖组件内的`static navigationOptions`设置. 
},{
	initialRouteName: 'Home', // 默认显示界面
	  //导航栏相关设置项
    // header:{
    // 	    //导航栏可见
    //         visible : false,
    //         //左上角的返回键文字, 默认是上一个页面的title
    //         backTitle : "返回",
    //         //导航栏的style
    //         headerStyle: {
    //             backgroundColor: '#fff'
    //         },
    //         //导航栏的title的style
    //         titleStyle: {
    //             color: 'green'
    //         }
    // },
    // title : 'home',
    // //导航栏的style
    //  headerStyle: {
    //             backgroundColor: '#fff'
    //  },
    //         //导航栏的title的style
    //  headerTitleStyle: {
    //          color: 'blue',
    //          //居中显示
    //          alignSelf : 'center',
    //      },

    // //是否允许右滑返回,在iOS上默认为true,在Android上默认为false
    // cardStack: {
    //         gesturesEnabled: true,
    // },


    onTransitionStart: ()=>{ console.log('导航栏切换开始'); },  // 回调
    onTransitionEnd: ()=>{ console.log('导航栏切换结束'); },  // 回调
});

AppRegistry.registerComponent('MyFirstProject', () => MyFirstProject);

       先说明下流程第一个界面HomeScreen跳转到第二个界面ChatScreen,然后可以返回到第一界面,在这里想要说的有两个重点:(1) title:`Chat with${navigation.state.params.user}` 注意“`”不是单引号,是和“~”在同一个按键的字符。(2)从第一个界面到第二界面参数是如何传递过去的,看下面的分析:

在HomeScreen界面中,通过const { navigate } =this.props.navigation 获取对象 navigate,那么navigate是个什么东西?来看下打印结果:

function navigate(routeName, params, action) {
    return navigation.dispatch(_NavigationActions2.default.navigate({
        routeName: routeName,
        params: params,
        action: action
}));

    不用意外navigate就是一个函数对象,参数一:需要跳转的界面(是在StackNavigator{}中声明的导航界面【例chat】),参数二:需要传递的数据(例{ user:'Lucy' }),参数三:处理数据或跳转的action (在这里先不管他)。

因此在下面我们使用到了:()=> navigate('Chat', { user:'Lucy' }) 跳转到ChatSrceen界面,并把{ user: 'Lucy' }传递过去。

   我们再来看看ChatSrceen是如果接受数据的,在ChatScreen中通过

const { params } =this.props.navigation.state获取数据,打印下params是?结果:{ user: 'Lucy' },

那么this.props.navigation.state 中为什么会存在对象{ user: 'Lucy' },那么我们再打印下this.props.navigation,结果:


好吧,在这里this.props.navigation 变成了一个真正的对象了,而不是函数了,可以看到这个对象中有个属性state,且属性state也是个对象,那么它的内容呢?如下:



很显然对象state中又有对象params,而params就是我们要找的数据{ user: 'Lucy' }。这也是数据传递的过程,至于为什么在HomeScreen中this.propes.navigation是个函数,而到了ChatScreen变成了真正的对象(我们需要的)了,其实上面是把this.props.navigation.navigate 赋值了给{ navigate }

下面是总的打印结果(方便对比):

















评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值