第二章 RN的第一个项目:导航+底部条切换+页面跳转

      上个篇幅主要介绍了RN的环境搭建,以及它自带的一个默认界面。实际开发的过程中,我们肯定是要重新设计的。那么最常见的就是做一个界面:有导航栏,底部条和一些文字按钮等,以及需要实现界面之间的跳转。类似如下图实现:
在这里插入图片描述
这个界面:1是导航栏;2是一个界面的文字说明;3是一个跳转button;4是底部条数据:总共有4个底部模块;
除了这个界面以外,我们还希望通过点击跳转button,能够跳转到一个详情介绍页面。参考下图:
在这里插入图片描述
我们可以通过点击返回,退回到首页。项目实现大致就是这些内容。下面简单介绍一下如何去实现。
(一)功能包下载:根目录下执行安装
      前一节也有说过,rn集成了很多功能包,都是通过npm下载和安装的。通过这些功能包的组合,我们来实现我们所需要的功能。

     npm add react-navigation
     npm add react-native-gesture-handler
     react-native link react-native-gesture-handler
     npm install react-native-tab-navigator --save

      主要就是上述的几个包,我们需要这么几个函数:createStackNavigator:创建导航栏;createBottomTabNavigator:底部条;createAppContainer这个是最终的展示界面。

(二)package.json安装文件列表:
      我们下载完包以后,检查一下是否安装成功:
在这里插入图片描述
这个里面还有一些其他的包,比如os就是用来判断平台的,目前没有用到,暂时不管。
(三)文件架构:
      我们需要建立4个底部模块和1个详情界面总共5个js文件,同时需要修改我们的入口文件App.js。首先看一下App.js文件的实现:

//1.先导入我们所需要的包 
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Image} from 'react-native';
import PropTypes from 'prop-types';
import { platform } from "os";

import TabNavigator from 'react-native-tab-navigator';   
//2.引入的底部条模块。注意:from引入的是一个js文件,虽然没有.js后缀。
import Home from './src/Component/Home';
import Article from './src/Component/Article';
import Owner from './src/Component/Owner';
import Order from './src/Component/Order';
import Details from './src/Component/Details';

/*****
3.我们需要使用到的三个方法:
createStackNavigator:创建导航栏
createBottomTabNavigator:创建底部条,这里我们抛弃了TabNavigator这种老方式定义
createAppContainer:创建最终的展示界面
******/
import {createStackNavigator} from 'react-navigation-stack'
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';

var navigation = null;
type Props = {};

//4.程序入口,使用export的方式给外部调用
export default class App extends Component<Props> {
  constructor(props){
    super(props);
    navigation = this.props.navigation;
    this.state = {
      selectedTab:'Home'
    }
  }

  //5.底部模块嵌套导航栏组成一个界面,最后合并成一个包含4个底部模块的完整界面
  topNavigator(){
        let topTabs = createBottomTabNavigator({
                //6.我们这里把首页和详情页放在一个控件里,属于一个空间
                HomeVC:createStackNavigator(
                    {
                        Home: { screen: Home },
                        DetailsVC: { screen: Details },
                    },{
                    //6.导航栏属性定义:标题,底部模块名字,底部模块选中和正常的图片
                    navigationOptions:{
                        headerTitle:'首页',
                        tabBarLabel: '首页',
                        tabBarIcon: ({ focused, tintColor }) => (
                            <Image
                              source={focused ? require('./image/home_s.png') : require('./image/home_n.png')}
                              style={{ width: 26, height: 26, tintColor: tintColor }}
                            />
                          )
                    } }),
                ArticleVC:createStackNavigator({screen:Article},{
                    navigationOptions:{
                       headerTitle:'文章',
                       tabBarLabel: '文章',
                       tabBarIcon: ({ focused, tintColor }) => (
                           <Image
                             source={focused ? require('./image/article_s.png') : require('./image/article_n.png')}
                             style={{ width: 26, height: 26, tintColor: tintColor }}
                           />
                         )
                    } }),
                OwnerVC:createStackNavigator({screen:Owner},{
                    navigationOptions:{
                      headerTitle:'我的',
                      tabBarLabel: '我的',
                      tabBarIcon: ({ focused, tintColor }) => (
                          <Image
                            source={focused ? require('./image/owner_s.png') : require('./image/owner_n.png')}
                            style={{ width: 26, height: 26, tintColor: tintColor }}
                          />
                        )
                    } }),
                OrderVC:createStackNavigator({screen:Order},{
                    navigationOptions:{
                        headerTitle:'订单',
                        tabBarLabel: '订单',
                        tabBarIcon: ({ focused, tintColor }) => (
                            <Image
                              source={focused ? require('./image/order_s.png') : require('./image/order_n.png')}
                              style={{ width: 26, height: 26, tintColor: tintColor }}
                            />
                          )
                    } }),
            },
            {
              //7.整个底部条的属性
             tabBarOptions: {
               activeTintColor: '#4BC1D2',
               inactiveTintColor: '#000',
               showIcon: true,
               showLabel: true,
               upperCaseLabel: false,
               pressColor: '#823453',
               pressOpacity: 0.8,
               style: {
                 backgroundColor: '#fff',
                 paddingBottom: 0,
                 borderTopWidth: 0.5,
                 borderTopColor: '#ccc',
               },
               labelStyle: {
                 fontSize: 12,
                 margin: 1
               },
               indicatorStyle: { height: 0 }, //8.android 中TabBar下面会显示一条线,高度设为 0 后就不显示线了
             },
             tabBarPosition: 'bottom',
             swipeEnabled: false,
             animationEnabled: false,
             lazy: true,
             backBehavior: 'none',
           }
        )
        //9.组合成一个最终展示界面
        return createAppContainer(topTabs)
    }

render(){
    let Pages = this.topNavigator()
    return <Pages/>
}
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
  },
  tabIcon:{
    width:23,
    height:23,
  }
});

再来看一下各个功能模块的界面实现代码,选Home.js来介绍一下,其他的模块都差不多,就不多一一展示了。

import React,{ Component } from 'react';
//1.这里要注意,我们所使用的视图类型必须在这里定义
import {
  StyleSheet,
  Text, Button,
  View, Image,TouchableOpacity,
} from 'react-native';

import PropTypes from 'prop-types';
import { platform } from "os";
import TabNavigator from 'react-native-tab-navigator';
import { createStackNavigator, createAppContainer } from 'react-navigation';

type props = {}

export default class Home extends Component<props>{
  static navigationOptions = {
      headerTitle: '首页',//对页面的配置
      tabBarLabel: '首页',
      tabBarIcon: ({ focused, tintColor }) => (
            <Image
              source={focused ? require('./image/home_s.png') : require('./image/home_n.png')}
              style={{ width: 26, height: 26, tintColor: tintColor }}
            />
          )
  };

  constructor(props){
    super(props);
  }

  //2.点击button我们跳转到详情界面
  render(){
    return (
         <View style={styles.container}>
            <Text style={styles.text}>首页</Text>
            <Button title='去详情页' onPress={() => this.props.navigation.navigate('DetailsVC')}/>
         </View>
    );
  }
}
const styles = StyleSheet.create({
    container:{
      flex:1,
      justifyContent:'center',
      alignItems:'center',
      backgroundColor:'grey'
    },
    text:{
      fontSize:30,
      color:'black'
    }
});

接下来再看一下详情界面。

import React,{ Component } from 'react';
import {
  StyleSheet,
  Text,
  View, Image,TouchableOpacity,
} from 'react-native';

import PropTypes from 'prop-types';
import { platform } from "os";
import TabNavigator from 'react-native-tab-navigator';
import { createStackNavigator, createAppContainer } from 'react-navigation';

type props = {}

export default class Details extends Component<props>{
   //1.重点说一下,通过设置标题
  static navigationOptions = {
      headerTitle: '详情'
  };

  constructor(props){
    super(props);
  }

  render(){
    const { navigate } = this.props.navigation;
    return (
      <View style={styles.container}>
            <Text style={styles.text}>详情展示页</Text>
      </View>
    );
  }
}
const styles = StyleSheet.create({
    container:{
      flex:1,
      justifyContent:'center',
      alignItems:'center',
      backgroundColor:'grey'
    },
    text:{
      fontSize:30,
      color:'black'
    }
});

主要的文件基本上就这些了。我们看一下文件目录。
在这里插入图片描述
注意:
1.目前最新的RN已经没有index.android.js和index.ios.js,统一成了index.js
2.ios和android代表的平台,相关的工程文件都放在各自对应的目录下。比如android目录打开就是这个样子:
在这里插入图片描述
这个就是一个典型的 Android Studio工程,我们如果需要做原生修改,就可以直接导入android这个目录。
注意:红箭头指向的assets目录是需要手工建立的,最后生成的bundle文件就放在这个目录下,我们再展开看一下:

在这里插入图片描述
通过编译,我们会生成一个index,android.bundle文件,包含了我们所有的源文件和资源。
3.image和src是我们自己建立的。我把资源图片放在了image下,js文件我放在了src目录下。
4.node_module目录下存放的是我们安装的react native包。
大致就是这样的一个目录结构。
(四)编译
1.Android版本:

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/

执行成功后,我们打开Android Studio运行就可以了。

2.Ios版本:
这个相对比较复杂,我们需要先在ios目录下建立一个目录,取名bundle,我们通过命令生成的离线包就安装在这个目录下。

react-native bundle --entry-file index.js  --platform ios --dev false --bundle-output ./ios/bundle/index.ios.jsbundle --assets-dest ./ios/bundle

执行成功后,我们会在bundle下看到一个bundle文件和assets目录。如下图所示:
在这里插入图片描述
assets目录存放的就是我们所需要的全部资源。
现在我们要把生成的index.ios.jsbundle编译进我们的工程,打开xcode,先导入整个bundle目录。在工程目录下按右键,在出现的菜单栏中选择Add files功能,
在这里插入图片描述
选择bundle目录整个导入:
在这里插入图片描述
这样就把所有的bundle文件导入进来了。如下图:
在这里插入图片描述
现在打开AppDelegate.m,我们要改一行代码,参考下图:
在这里插入图片描述
注释1处使用的是原来的index文件,我们现在用的是离线包,因此需要改成2处的设计。

接下来还要配置网络访问白名单,打开info.plist :
在这里插入图片描述
一定要保证是YES,开启才能使用。

(五)总结
      RN编译和运行经常会出现一个莫名其妙的错误,还是要多尝试去写,参考官网:https://reactnavigation.org/docs/zh-Hans/hello-react-navigation.html,大部分的问题都可以解决。
网上还多帖子都是用的比较旧的工程,只能仅供参考,需要自己多尝试和多学习。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值