跨平台开发RN-简介、布局

React Native 简介

  1. 什么是React Native?
    1. Facebook于2015年9月15日发布React Native
    2. 它充分利用了Facebook现有的业务轮子, 其核心设计理念:既拥有Native的用户体验、又保留React的开发效率。
    3. React Native基本完成了对多端的支持,实现了真正意义上的面向配置开发: 开发者可以灵活的使用HTML和CSS布局,使用React语法构建组件,实现:H5, Android, iOS 多端代码的复用
    4. 广大开发者可以使用JavaScript和React开发跨平台移动应用
    5. React Native提倡组件化开发: 即提供一个个封装好的组件,组件相互嵌套形成新的组件
    6. 目前react native在iOS上仅支持ios7以上,Android仅支持Android4.1以上版本;
      1. github地址: https://github.com/facebook/react-native
      2. 官网文档: http://facebook.github.io/react-native/docs/getting-started.html
      3. 中文网文档:http://reactnative.cn/docs/0.42/getting-started.html(非官方,但文档不错

配置React Native开发环境

  1. 环境需求
    1. 安装Homebrew (方法百度)
    2. 安装WatchMan
      1. 该插件用于监控bug文件,并且可以触发指定的操作
      2. 安装方式:brew install watchman
    3. 安装Flow
      1. flow是一个 JavaScript 的静态类型检查器,建议安装它,以方便找出代码中可能存在的类型错误
      2. 安装方式:brew install flow
  2. React Native安装
    1. 安装React Native :npm install -g react-native-cli
  3. React Native的第一个应用
    1. 执行命令,生成一个工程
      1. cd到工程文件夹下
      2. 执行命令:react-native init RNTestProduct
    2. 注意:由于众所周知的网络原因,react-native命令行从npm官方源拖代码时会遇上麻烦。请将npm仓库源替换为国内镜像:

       npm config set registry https://registry.npm.taobao.org
       npm config set disturl https://npm.taobao.org/dist
      
    3. 目录结构分析
      1. ios: iOS的原生项目
        1. 打开可以用Xcode直接运行
        2. 运行过程中会自动打开终端,运行react-native服务器
      2. android: 安卓的原生项目
      3. node_modules: 是为Node.js存放和管理npm包资源,也包含React Native框架文件。
      4. index.js: 打包 app 时进入 react native(js 部分) 的入口文件(0.49 以后安卓、ios 共用一个入口文件)
      5. App.js 可以理解为 react native(js 部分) 代码部分的入口文件,比如整个项目的路由在这里导入
      6. _test_/ 测试用(暂未使用)
      7. app.json 项目说明,主要给原生 app 打包用,包括项目名称和手机桌面展示名称 React Native : 0.41 app.json
      8. package.json 项目依赖包配置文件
      9. yarn.lock yarn 包管理文件
  4. Android开发环境需求
    1. 安装最新版的JDK: ttp://www.oracle.com/technetwork/java/javase/downloads,然后安装
    2. 下载安装Android Studio:https://developer.android.com/studio/index.html
      1. 安装时可以不勾选:Android Virtual Device,不需要这个模拟器
  5. 安装Genymotion虚拟机
    1. Genymotion是一个第三方模拟器,它比Google官方的模拟器更易设置且性能更好。但是,它只针对个人用户免费。
    2. Genymotion官网注册: https://www.genymotion.com/
    3. 下载genymotion: https://www.genymotion.com/download/
    4. 打开Genymotion,如果你尚未安装VirtualBox,它有可能会提示你安装,根据提示下载安装即可,然后再次点开
    5. 登录账号,有很多模拟器供下载。也可以自定义模拟器下载。
    6. 按下⌘+M可以打开开发者菜单(在安装并启动了React Native应用之后)
  6. 运行安卓原生项目
    1. 打开Genymotion,选择一个模拟器机型运行起来
    2. 用Android Studio打开React Native项目目录的Android文件夹,然后运行即可
      1. Android Studio会自动识别模拟器
    3. 注意:一定要将react-native的服务器启动起来,否则运行项目报错
      1. 可以用Xcode运行一下iOS原生项目,react-native服务就会自动在终端启动。
  7. 编辑器的使用
    1. 使用webstorm,用webstorm打开RNTestProduct文件
    2. 点击右上角的Add Configuration->点击左上角的+->在列表中选择React Native
    3. 修改名称,然后选择应用,OK即可。
    4. 环境配置:偏好设置->语言&框架->JavaScript->js语言版本选择React JSX->应用即可
    5. 修复由于格式问题webstorm爆红
      1. 选中代码,右击->Fix USELint Problems
      2. 或者字节设置快捷键: 偏好设置->快捷键->搜索Fix 找到Fix USELint Problems,右击添加快捷键,比如:command+0
  8. 管理React Native库的版本
    1. 由于RN的版本更新非常快,因此要对版本进行管理
    2. 查看本地的React Native的版本

       react-native --version
      
    3. 更新本地的React Native的版本

       npm update -g react-native-cli
      
    4. 查询react-native的npm包最新版本

       npm info react-native
      
    5. 升级或者降级npm包的版本

       npm install --save react-native@0.18
      

React Native基本使用

  1. 打开genymotion,选择一个模拟器运行
  2. 启动RN服务:
    1. cd到项目根目录,输入:react-native start
  3. 用AS打开项目目录下的Android源码,然后运行,此时项目在genymotion模拟器上运行
  4. 此时就可以关闭AS了,AS的功能就是让RN的项目安装在genymotion上
  5. 重新打开模拟器项目。
  6. APP.js中写代码,双击R刷新模拟器就可以看到修改的内容
  7. 注意:
    1. AS仅仅是将项目安装在genymotion上,只要没有修改Android源码,就不需要重新运行
    2. RN的开发条件:
      1. 启动RN服务器
      2. 将项目安装到genymotion上
      3. 一共编辑器编写代码
    3. 下次运行就不需要AS了。
  8. 模拟器的使用方法:

     双击R,刷新模拟器
     cmd+M:打开菜单
    
  9. 代码编辑
    1. 之前的RN项目生成目录都有index.android.jsindex.ios.js分别写各自的代码,但是0.46以后,只有一个入口就是index.js,初始化代码在App.js
    2. 由于网上的资料都是旧版的,而且App.js中的初始化代码比较扯,因此为了便于学习,那么久需要采用旧的方法
      1. 在项目根目录下新建一个Entry.js
      2. 内部初始化代码如下:

         import React, {Component} from 'react';
         import {View, StyleSheet} from 'react-native';
                    
         //貌似必须这么写
         export default class Enty extends Component {
           render() {
             return (
                 <View style={styles.container}>
                    
                 </View>
             );
           }
         }
         const styles = StyleSheet.create({
           container: {
             flex: 1,
             backgroundColor: '#F5FCFF',
           },
         });
        
      3. 在index.js中修改

         import {AppRegistry} from 'react-native';
         import App from './App';
         import {name as appName} from './app.json';
         //1. 导入Enty类
         import Enty from './Entry';
         //2. APP的加载类为Enty
         AppRegistry.registerComponent(appName, () => Enty);
        
      4. 这样就可以在Entry.js中写旧的RN代码了
    3. 如何clone RN项目
     1. git clone 地址
     2. npm install
     3. react-native start
     4. 打开genymotion模拟器
     5. 打开Android studio 运行
    

React Native的布局

View组件

  1. 组件View,就等同于iOS中的UIView, Android中的android.view,以及网页中的<div>标签。它是所有组件的父组件。
  2. View组件中常见的属性

     Flexbox 弹性布局
     Transforms  动画属性
     backfaceVisibility enum('visible', 'hidden')    定义界面翻转的时候是否可见
     opacity number 设置透明度,取值从0-1;
     overflow enum('visible', 'hidden')  设置内容超出容器部分是显示还是隐藏;
     elevation number 高度   设置Z轴,可产生立体效果。
     backgroundColor 
     ...
    

FlexBox布局

  1. 什么是FlexBox布局?
    1. 弹性盒模型(The Flexible Box Module),又叫Flexbox。是css3中引入的布局-弹性盒子模型,旨在通过弹性的方式来对齐和分布容器中内容的空间,使其能适应不同屏幕的宽度;
    2. 通俗的说就是用来决定父盒子与子盒子之间的关系:尺寸、位置
    3. Flex布局主要思想是:让容器有能力让其子项目能够改变其宽度、高度(甚至是顺序),以最佳方式填充可用空间;
  2. 在CSS中,常规的布局是基于块和内联流方向(从左到右,从上到下),而Flex布局是基于flex-flow流
  3. flex-flow流:
    1. 确定主轴的方向:main axis
    2. 确定侧轴方向:cross axis
    3. 就是控件自动会从左向右排列,还是从上到下排列
  4. Flexbox的常用属性
    1. 容器属性
      1. flexDirection: row | row-reverse | column | column-reverse
        1. 作用:设置主轴的方向,给父控件设置主轴,决定内部子控件自动布局的方向
        2. 值分析:
          1. row:主轴为水平方向,起点在左端,子控件自动从左向右布局
          2. row-reverse:主轴为水平方向,起点在右端
          3. column(默认):主轴为垂直方向,起点在顶端
          4. column-reverse:主轴为垂直方向,起点在底端
        3. 注意:移动端只会用到row、column这2种,默认为column。
      2. justifyContent:flex-start | flex-end | center | space-between | space-around
        1. 作用:设置主轴方向上的对齐方式,(比如主轴为column,那么就是设置垂直方向上的对齐方式),设置子内容的对齐方式,相当于word的左、右中对齐方式
          1. 举例:比如主轴为column,对齐方式为center,那就是垂直居中
        2. 值分析
          1. flex-start(默认值):子控件向一行的起始位置靠齐。
          2. flex-end:子控件向一行的结束位置靠齐。
          3. center:子控件向一行的中间位置靠齐。
          4. space-between:子控件会平均地分布在行里。第一个伸缩项目一行中的最开始位置,最后一个伸缩项目在一行中最终点位置。
          5. space-around:子控件会平均地分布在行里,两端保留一半的空间。
        3. 如下图: 图1
      3. alignItems: flex-start | flex-end | center | baseline | stretch
        1. 作用:设置侧轴方向上的对齐方式,就是与主轴垂直方向上子控件的对齐方式
        2. 值分析:
          1. flex-start:子控件在侧轴起点边的外边距紧靠住该行在侧轴起始的边。
          2. flex-end:子控件在侧轴终点边的外边距靠住该行在侧轴终点的边 。
          3. center:子控件的外边距盒在该行的侧轴上居中放置。
          4. baseline:子控件根据他们的基线对齐。(web使用,移动端不适用)
          5. stretch(默认值):子控件拉伸填充整个伸缩容器。此值会使项目的外边距盒的尺寸在遵照「min/max-width/height」属性的限制下尽可能接近所在行的尺寸。
        3. 如下图: 图1
        4. 总结:通过上面三个属性可以实现子控件的水平、垂直居中
      4. flexWrap: nowrap | wrap | wrap-reverse
        1. 作用:设置容器的子控件自动多行布局
        2. 值分析:
          1. nowrap(默认值):伸缩容器单行显示,多出的不显示
          2. wrap:伸缩容器多行显示,“ltr”排版下,伸缩项目从左到右排列;“rtl”排版上伸缩项目从右向左排列
          3. wrap-reverse:伸缩容器多行显示,“ltr”排版下,伸缩项目从右向左排列;“rtl”排版下,伸缩项目从左到右排列。(和wrap相反)
    2. 元素属性
      1. flex
        1. 设置当前盒子占据父盒子的宽度比例
        2. “flex-grow”、“flex-shrink”和“flex-basis”三个属性的缩写。
        3. 其中第二个和第三个参数(flex-shrink、flex-basis)是可选参数。
        4. 默认值为“0 1 auto”
        5. 宽度 = 弹性宽度 * (flex-grow/sum(flex-grow))
        6. 弹性宽度指父盒子的宽度
        7. 举例:
          1. 情况1:子控件全部设置了flex-grow,则所有子控件按照比例显示
          2. 情况2:有的设置了flex-grow,有的没有设置,则设置了flex-grow的子控件宽度= (父盒子宽度-没有设置flex-grow的默认宽度)*(flex-grow/所有子控件flex-grow的和) 图1

            1. 第一个text的flex设置为1,第二个text的flex设置为2,第三个text没有设置flex
            2. 那么第一个text的宽度就是:(父控件宽度-第三个text默认宽度)*1/3
      2. alignSelf: auto | flex-start | flex-end | center | baseline | stretch
        1. 在父盒子中使用alignItems后,该父盒子所有的子控件都要按照alignItems属性对齐,那么如果有某个盒子想自己单独设置呢?这就是alignSelf的作用
        2. 单独设置对齐方式,可以覆盖掉alignItems的对齐方式

内边距、外边距、绝对定位

  1. 内边距(与css一样):padding、paddingBottom、paddingTop、paddingLeft、paddingRight
  2. 外边距(与css一样):margin、marginBottom、marginTop、marginLeft、marginRight
  3. 相对绝对定位
    1. 与css定位不同,在React Native中定位不需要再父组件中设置position属性。
    2. 通常情况下设置positionabsolute,定位的效果是一样的,但是如果父组件设置了内边距,position会做出相应的定位改变,而absolute则不会。
    3. 比对下面:

       //相对对定位
       otherLoginStyle: {
           //有效
           paddingTop: 50,
           position: 'relative',
           //这两个无效
           bottom: 10,
           left: 20,
       }
       //绝对定位
       otherLoginStyle: {
           //无效
           paddingTop: 50,
           position: 'absolute',
           //这两个有效
           bottom: 10,
           left: 20,
       }
      

获取屏幕宽、高、分辨率

  1. 导入react-native下的Dimensions

     import {View, StyleSheet, Text, Image, Dimensions} from 'react-native';
    
  2. 获取相应值

     //宽、高、分辨率
     var {width,height,scale} = Dimensions.get('window');
    
Table of Contents