zoukankan      html  css  js  c++  java
  • React Native移动框架功能研究

    React Native移动框架功能研究


    此篇只研究React Native框架的功能。

    一、React Natvie是什么

    React Native是使用React(或者说JS)来开发原生APP的框架。

    二、React Native的愿景

    1.提供一直的跨平台开发原生APP的一直体验。

    2.使用JSReact提高跨平台开发效率。

    三、React Native提供的特性

    1.提供了丰富的原生组件,可以是APP获得平台一致的视觉效果和体验,同时获得最佳的性能和流畅性。

    
    
    // iOS & Android
    
    var React = require('react-native');
    var { ScrollView, TouchableHighlight, Text } = React;
    
    var TouchDemo = React.createClass({
      render: function() {
        return (
          <ScrollView>
            <TouchableHighlight onPress={() => console.log('pressed')}>
              <Text>Proper Touch Handling</Text>
            </TouchableHighlight>
          </ScrollView>
        );
      },
    });
    
    

    2.JS代码和原生平台之间的所有操作都是异步执行的,原生模块可以根据需要自由创建线程。同时两者之间的通讯是完全可序列化的,这使其可以借助Chorme开发这工具进行调试。

    3.提供强大的触控事件处理系统,可以在复杂的UI层次结构下方便的处理触控事件。

    // iOS & Android
    
    var React = require('react-native');
    var { ScrollView, TouchableHighlight, Text } = React;
    
    var TouchDemo = React.createClass({
      render: function() {
        return (
          <ScrollView>
            <TouchableHighlight onPress={() => console.log('pressed')}>
              <Text>Proper Touch Handling</Text>
            </TouchableHighlight>
          </ScrollView>
        );
      },
    });
    4.通过Flexbox简化UI布局,提供高性能机制声明样式和布局,并可直接应用到组件中。
    // iOS & Android
    
    var React = require('react-native');
    var { Image, StyleSheet, Text, View } = React;
    
    var ReactNative = React.createClass({
      render: function() {
        return (
          <View style={styles.row}>
            <Image
              source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
              style={styles.image}
            />
            <View style={styles.text}>
              <Text style={styles.title}>
                React Native
              </Text>
              <Text style={styles.subtitle}>
                Build high quality mobile apps using React
              </Text>
            </View>
          </View>
        );
      },
    });
    var styles = StyleSheet.create({
      row: { flexDirection: 'row', margin: 40 },
      image: {  40, height: 40, marginRight: 10 },
      text: { flex: 1, justifyContent: 'center'},
      title: { fontSize: 11, fontWeight: 'bold' },
      subtitle: { fontSize: 10 },
    });
    5.提供灵活的机制,方便自定义原生视图和模块。
    四、React Native的功能
    1.样式
    React NativeJS中定义和引用样式。可以通过StyleSheet定义样式
    var styles = StyleSheet.create({
      base: {
         38,
        height: 38,
      },
      background: {
        backgroundColor: '#222222',
      },
      active: {
        borderWidth: 2,
        borderColor: '#00ff00',
      },
    });
    在组件中使用样式
    <Text style={styles.base} />
    <View style={styles.background} />
    同时可以接受多个样式,后边的会覆盖前边的样式
    <View style={[styles.base, styles.background]} />
    可以结合表达式控制是否应用样式
    <View style={[styles.base, this.state.active && styles.active]} />
    也可以直接在元素中声明样式,但是每次渲染都会重建样式,影响性能。
    <View
      style={[styles.base, {
         this.state.width,
        height: this.state.width * this.state.aspectRatio
      }]}
    />
    样式也可以作为参数传递
    var List = React.createClass({
      propTypes: {
        style: View.propTypes.style,
        elementStyle: View.propTypes.style,
      },
      render: function() {
        return (
          <View style={this.props.style}>
            {elements.map((element) =>
              <View style={[styles.element, this.props.elementStyle]} />
            )}
          </View>
        );
      }
    });
    
    // ... 在别的文件中引用List组件 ...
    <List style={styles.list} elementStyle={styles.listElement} />
    2.图片
    加载本地静态图片,图片基于当前js的目录。如果带有平台相关的扩展名,则系统自动根据当前的系统平台自动加载相关的图片,例如my-icon.ios.png
    <Image source={require('./my-icon.png')} />
    使用@2x@3x这样的文件名后缀,可以为不同的屏幕精度提供图片
    可以在React Native中直接使用内嵌到APP中的图片资源
    <Image source={{uri: 'app_icon'}} style={{ 40, height: 40}} />
    可以加载网络图片,但是需要手动指定图片大小
    <Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
           style={{ 400, height: 400}} />
    通过将元素嵌套到Image中实现背景图片
    return (
      <Image source={...}>
        <Text>Inside</Text>
      </Image>
    );
    3.手势触控系统
    提供TouchableTouchableHighlight来定义可触控控件。响应者的声明周期如下:
    是否愿意成为响应者
    View.props.onStartShouldSetResponder(开始触摸的时候是否愿意)
    View.props.onMoveShouldSetResponder(如果不是响应者,则每次开始移动触控点时询问是否原因)
    如果愿意成为响应者,则接下来开始尝试成为响应者
    View.props.onResponderGrant(成功成为响应者)
    View.props.onResponderReject(被拒绝成为响应者)
    如果成功成为响应者,则开始具体的响应触控事件
    View.props.onResponderMove(响应屏幕手指移动)
    View.props.onResponderRelease(响应屏幕手指离开)
    View.props.onResponderTerminationRequest(其他组件请求接替响应者,返回true则释放自己响应者角色)
    View.props.onResponderTerminate(响应者角色已交出)
    
    onStartShouldSetResponderonMoveShouldSetResponder是以冒泡的形式调用的,即嵌套最深的节点最先调用。如果某个父View会希望能先成为响应者。我们可以利用“捕获期”来解决这一需求
    View.props.onStartShouldSetResponderCapture
    View.props.onMoveShouldSetResponderCapture
    4.动画
    用于全局的布局动画LayoutAnimation,和用于创建更精细的交互控制的动画AnimatedAnimated库使得开发者可以非常容易地实现各种各样的动画和交互方式,并且具备极高的性能。它包括两个值类型,Value用于单个的值,而ValueXY用于向量值;还包括三种动画类型,springdecay,还有timing,以及三种组件类型,ViewTextImage。我们可以使用Animated.createAnimatedComponent方法来对其它类型的组件创建动画
    class Playground extends React.Component {
      constructor(props: any) {
        super(props);
        this.state = {
          bounceValue: new Animated.Value(0),
        };
      }
      render(): ReactElement {
        return (
          <Animated.Image                         // 可选的基本组件类型: Image, Text, View
            source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}}
            style={{
              flex: 1,
              transform: [                        // `transform`是一个有序数组(动画按顺序执行)
                {scale: this.state.bounceValue},  // 将`bounceValue`赋值给 `scale`
              ]
            }}
          />
        );
      }
      componentDidMount() {
        this.state.bounceValue.setValue(1.5);     // 设置一个较大的初始值
        Animated.spring(                          // 可选的基本动画类型: spring, decay, timing
          this.state.bounceValue,                 // 将`bounceValue`值动画化
          {
            toValue: 0.8,                         // 将其值以动画的形式改到一个较小值
            friction: 1,                          // Bouncier spring
          }
        ).start();                                // 开始执行动画
      }
    }
    多个动画可以通过parallel(同时执行)、sequence(顺序执行)、staggerdelay来组合使用
    Animated.sequence([            // 首先执行decay动画,结束后同时执行spring和twirl动画
      Animated.decay(position, {   // 滑行一段距离后停止
        velocity: {x: gestureState.vx, y: gestureState.vy}, // 根据用户的手势设置速度
        deceleration: 0.997,
      }),
      Animated.parallel([          // 在decay之后并行执行:
        Animated.spring(position, {
          toValue: {x: 0, y: 0}    // 返回到起始点开始
        }),
        Animated.timing(twirl, {   // 同时开始旋转
          toValue: 360,
        }),
      ]),
    ]).start();  
    LayoutAnimation允许在全局范围内创建和更新动画,它常用来更新flexbox布局
    var App = React.createClass({
      componentWillMount() {
        // 创建动画
        LayoutAnimation.spring();
      },
    
      getInitialState() {
        return { w: 100, h: 100 }
      },
    
      _onPress() {
        // 让视图的尺寸变化以动画形式展现
        LayoutAnimation.spring();
        this.setState({w: this.state.w + 15, h: this.state.h + 15})
      },
    
      render: function() {
        return (
          <View style={styles.container}>
            <View style={[styles.box, { this.state.w, height: this.state.h}]} />
            <TouchableOpacity onPress={this._onPress}>
              <View style={styles.button}>
                <Text style={styles.buttonText}>Press me!</Text>
              </View>
            </TouchableOpacity>
          </View>
        );
      }
    });
    如果对性能要求比较高setNativeProps方法可以使我们直接修改基于原生视图的组件的属性,而不需要使用setState来重新渲染整个组件树,从而可以使我们获得较好的性能。此时应该注意被render重新调用的时候覆盖掉
    5.提供的调试工具
    开发者菜单
    Chrome开发者工具
    React开发工具插件
    FPS监视器
    6.自动化测试
    使用Jest进行单元测试,使用Travis作为持续集成系统。
    集成测试和快照测试只使用IOS
    7.JS环境
    IOSAndroid模拟器和真机上,使用的是JavaScriptCore
    Chorme调试时,代码运行在V8引擎中。
    React Native0.5.0版本开始已经内置Babel转换器,使我们可以使用最新的js语法编写代码
    8.导航器
    官方提供提供通用跨平台的Navigatorjs编写方便扩展。
    开源社区提供的NavigatorIOS,只能在IOS中使用,依赖Object-c,积压bug无人解决,不建议使用。
    9.特定平台代码
    将代码放在特定平台的文件夹下
    /common/components/   
    /android/components/   
    /ios/components/
    组件命名中添加平台标志
    BigButtonIOS.js
    BigButtonAndroid.js
    特定平台扩展名
    BigButton.ios.js
    BigButton.android.js
    
    js中判断当前平台
    var {Platform} = React;
    
    var styles = StyleSheet.create({
      height: (Platform.OS === 'ios') ? 200 : 100,
    });
    、已知存在的问题
    模块和原生视图缺失,比如MapsSpinner

     某些属性仅仅支持单个平台

     有一些已经存在的组件和API没能进行统一抽象为通用的,比如ActivityIndicatorIOSProgressBarAndroid

        overflow样式在Android中无法使用

     不支持Android M6.0)的权限

        NG图片的内存问题





    
    



  • 相关阅读:
    2014复习提纲
    string库与char[]
    扩展欧几里得算法及其应用
    1002 [FJOI2007]轮状病毒
    node源码详解(三)—— js代码在node中的位置,process、require、module、exports的由来
    node源码详解(二 )—— 运行机制 、整体流程
    node源码详解 (一)
    html 第一天随记(个人不常用的标签)
    Siebel电信业务流程
    Siebel层次架构
  • 原文地址:https://www.cnblogs.com/wufengtinghai/p/5229333.html
Copyright © 2011-2022 走看看