一、特定平台代码

  React Native提供了两种方法来区分平台:

  • 使用Platform模块;
  • 使用特定平台扩展名;

  1、Platform模块

  React Native提供了一个检测当前运行平台的模块;Platform适用于对一小部分代码需要按照平台定制的情况;

import { Platform, StyleSheet } from "react-native";

const styles = StyleSheet.create({
height: Platform.OS === "ios" ? 200 : 100
});

  Platform.OS 在iOS上会返回iOS,而在安卓设备或模拟器上则返回android;还要一个实用的方法是Platform.select()

import { Platform, StyleSheet } from "react-native";

const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: "red"
},
android: {
backgroundColor: "blue"
}
})
}
});

  1.1 检测Android版本

  在Android上,Version属性是一个数字,标识Andorid的api level;

import { Platform } from "react-native";

if (Platform.Version === 25) {
console.log("Running on Nougat!");
}

  1.2 检测iOS版本

  在iOS上,Version属性是-[UIDevice systemVersion]的返回值,具体形式为一个表示当前系统版本的字符串。如:“10.3”

import { Platform } from "react-native";

const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
console.log("Work around a change in behavior");
}

  2、特定平台扩展名

  当不同平台的代码逻辑较为复杂时,最好是放到不同的文件里,这时候我们可以使用特定平台扩展名。React Native 会检测某个文件是否具有.ios.或是.android.的扩展名,然后根据当前运行的平台自动加载正确对应的文件。

***.ios.js
***.android.js

二、React Native中使用图片

  1、静态图片资源

  React Native提供了一个统一的方式来管理iOS和Android应用中的图片。要往App中添加一个静态图片,只需要把图片放到代码文件夹某处,就可以直接引用。

<Image source={require('./my-icon.png')} />

  如果你有my-icon.ios.pngmy-icon.android.png,Packager 就会根据平台而选择不同的文件。

  而且还可以使用@2x,@3x这样的文件名后缀,来为不同的屏幕精度提供图片。

.
├── button.js
└── img
├── check.png
├── check@2x.png
└── check@3x.png

  Packager会打包所有的图片并且依据屏幕精度提供对应的资源。譬如:iPhone 7 会使用check@2x.png,而 iPhone 7 plus 或是 Nexus 5 上则会使用check@3x.png。如果没有图片恰好满足屏幕分辨率,则会自动选中最接近的一个图片。

  这样会带来如下的一些好处:

  (1)iOS和Android一致的文件系统;

  (2)图片和JS代码处在相同的文件夹,这样组件就可以包含自己所用的图片而不用单独去设置;

  (3)不需要全局命名。不用担心图片名字冲突问题。

  (4)只有实际被用到(即require)的图片才会被打包到app。

  注意:为了使新的图片资源机制正常工作,require中的图片名字必须是一个静态字符串(不能使用变量,因为require是在编译时期执行,而非运行时期执行)。通过require方式引用的图片包含图片尺寸信息,不需要重新设置width和height.

  2、使用混合App的图片资源

  如果你在编写一个混合 App(一部分 UI 使用 React Native,而另一部分使用平台原生代码),也可以使用已经打包到 App 中的图片资源(以拖拽的方式放置在 Xcode 的 asset 类目中,或是放置在 Android 的 drawable 目录里)。注意此时只使用文件名,不带路径也不带后缀:

<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />

  对于放置在 Android 的 assets 目录中的图片,还可以使用asset:/ 前缀来引用:

<Image source={{uri: 'asset:/app_icon.png'}} style={{width: 40, height: 40}} />

  注意:这些做法并没有任何安全检查。你需要自己确保图片在应用中确实存在,而且还需要指定尺寸。

  3、Uri数据图片  

  有时候你可能拿到的是图片的 base64 数据,此时可以使用'data:'格式来显示图片。请注意,你需要手动指定图片的尺寸

// 请记得指定宽高!
<Image
style={{
width: 51,
height: 51,
resizeMode: 'contain',
}}
source={{
uri:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
}}
/>

  4、缓存控制(仅iOS)

  缓存资源属性提供了控制网络层与缓存交互的方式。

  • default:使用原生平台默认策略;
  • reload:URL的数据将从原始地址加载。不使用现有的缓存数据。
  • force-cache:现有的缓存数据将用于满足请求,忽略其期限或到期日。如果缓存中没有对应请求的数据,则从原始地址加载。
  • only-if-cached:现有的缓存数据将用于满足请求,忽略其期限或到期日。如果缓存中没有对应请求的数据,则不尝试从原始地址加载,并且认为请求是失败的。
<Image
source={{
uri: 'https://facebook.github.io/react/logo-og.png',
cache: 'only-if-cached',
}}
style={{width: 400, height: 400}}
/>

三、动画效果的使用

  React Native 提供了两个互补的动画系统:用于创建精细的交互控制的动画Animated和用于全局的布局动画LayoutAnimation

  1、Animated

  Animated使得开发者可以非常容易地实现各种各样的动画和交互方式,并且具备极高的性能。Animated旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用简单的start/stop方法来控制动画按顺序执行。 Animated仅封装了四个可以动画化的组件:ViewTextImageScrollView,不过你也可以使用Animated.createAnimatedComponent()来封装你自己的组件。下面是一个在加载时带有淡入动画效果的视图:  

import React from 'react';
import { Animated, Text, View } from 'react-native'; class FadeInView extends React.Component {
state = {
fadeAnim: new Animated.Value(0), // 透明度初始值设为0
} componentDidMount() {
Animated.timing( // 随时间变化而执行动画
this.state.fadeAnim, // 动画中的变量值
{
toValue: 1, // 透明度最终变为1,即完全不透明
duration: 10000, // 让动画持续一段时间
}
).start(); // 开始执行动画
} render() {
let { fadeAnim } = this.state; return (
<Animated.View // 使用专门的可动画化的View组件
style={{
...this.props.style,
opacity: fadeAnim, // 将透明度指定为动画变量值
}}
>
{this.props.children}
</Animated.View>
);
}
} // 然后你就可以在组件中像使用`View`那样去使用`FadeInView`了
export default class App extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
<Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
</FadeInView>
</View>
)
}
}

  2、LayoutAnimation API

  LayoutAnimation允许你在全局范围内创建更新动画,这些动画会在下一次渲染或布局周期运行。它常用来更新 flexbox 布局,因为它可以无需测量或者计算特定属性就能直接产生动画。尤其是当布局变化可能影响到父节点(譬如“查看更多”展开动画既增加父节点的尺寸又会将位于本行之下的所有行向下推动)时,如果不使用LayoutAnimation,可能就需要显式声明组件的坐标,才能使得所有受影响的组件能够同步运行动画。  

  尽管LayoutAnimation非常强大且有用,但它对动画本身的控制没有Animated或者其它动画库那样方便,所以如果你使用LayoutAnimation无法实现一个效果,那可能还是要考虑其他的方案。

  要在Android上使用 LayoutAnimation,那么目前还需要在UIManager中启用:

// 在执行任何动画代码之前,比如在入口文件App.js中执行
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
import React from 'react';
import {
NativeModules,
LayoutAnimation,
Text,
TouchableOpacity,
StyleSheet,
View,
} from 'react-native'; const { UIManager } = NativeModules; UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true); export default class App extends React.Component {
state = {
w: 100,
h: 100,
}; _onPress = () => {
// Animate the update
LayoutAnimation.spring();
this.setState({w: this.state.w + 15, h: this.state.h + 15})
} render() {
return (
<View style={styles.container}>
<View style={[styles.box, {width: 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>
);
}
} const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 200,
height: 200,
backgroundColor: 'red',
},
button: {
backgroundColor: 'black',
paddingHorizontal: 20,
paddingVertical: 15,
marginTop: 15,
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
},
});

【React Native】进阶指南之一(特定平台、图片加载、动画使用)的更多相关文章

  1. iOS开发——图形编程Swift篇&CAShapeLayer实现圆形图片加载动画

    CAShapeLayer实现圆形图片加载动画 几个星期之前,Michael Villar在Motion试验中创建一个非常有趣的加载动画. 下面的GIF图片展示这个加载动画,它将一个圆形进度指示器和圆形 ...

  2. 使用CAShapeLayer来实现圆形图片加载动画[译]

    原文链接 : How To Implement A Circular Image Loader Animation with CAShapeLayer 原文作者 : Rounak Jain 译文出自 ...

  3. CSS3实现的图片加载动画效果

    来源:GBin1.com 使用CSS3实现的不同图片加载动画效果,支持响应式,非常适合针对瀑布流布局图片动态加载特效进行增强! HTML <ul class="grid effect- ...

  4. iOS-swift环形进度指示器+图片加载动画

    demo.gif 如图,这个动画的是如何做的呢? 分析: 1.环形进度指示器,根据下载进度来更新它 2.扩展环,向内向外扩展这个环,中间扩展的时候,去掉这个遮盖 一.环形进度指示器 1.自定义View ...

  5. Vue回炉重造之图片加载性能优化

    前言 图片加载优化对于一个网站性能好坏起着至关重要的作用.所以我们使用Vue来操作一波.备注 以下的优化一.优化二栏目都是我自己封装在Vue的工具函数里,所以请认真看完,要不然直接复制的话,容易出错的 ...

  6. [RN] React Native 使用开源库 react-native-image-crop-picker 实现图片选择、图片剪裁

    React Native 使用开源库 react-native-image-crop-picker 实现图片选择.图片剪裁 该库可以实现启动本地相册和照相机来采集图片,并且提供多选.图片裁剪等功能,支 ...

  7. 【独家】React Native 版本升级指南

    前言 React Native 作为一款跨端框架,有一个最让人头疼的问题,那就是版本更新.尤其是遇到大版本更新,JavaScript.iOS 和 Android 三端的配置构建文件都有非常大的变动,有 ...

  8. Aandroid 图片加载库Glide 实战(一),初始,加载进阶到实践

    原文: http://blog.csdn.net/sk719887916/article/details/39989293 skay 初识Glide 为何使用 Glide? 有经验的 Android ...

  9. fackbook的Fresco (FaceBook推出的Android图片加载库-Fresco)

    [Android开发经验]FaceBook推出的Android图片加载库-Fresco   欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件 ...

随机推荐

  1. Ajax获取网页添加到div中

    1:利用DOM获取该 div 的 ID,然后清空该DIV的内容(如果你需要接着里面的内容添加可不要清空):需要注意点是清空最好用“ empty()  ”: 2: 把  async设成true ,否则又 ...

  2. Centos6、Centos7防火墙基本操作整理

    Centos7: 查看防火墙状态: firewall-cmd --state 开启防火墙: systemctl start firewalld.service 关闭防火墙(重启失效): systemc ...

  3. SpringCloud微服务实现生产者消费者+ribbon负载均衡

    一.生产者springcloud_eureka_provider (1)目录展示 (2)导入依赖 <dependency> <groupId>org.springframewo ...

  4. Java用广度优先搜索快速搜索文件

    背景 在开发的过程中,经常需要在文件系统里按某些条件搜索文件,比如音乐播放器扫描音乐,而搜索文件,大多人喜欢用递归的方式,而这也是最容易想到的方式.递归方式如果文件夹很深就容易造成栈溢出,而且不断的压 ...

  5. 【zabbix告警监控】配置zabbix监控nginx服务

    zabbix监控nginx,nginx需要添加--with-http_stub_status模块 使用zabbix监控nginx,首先nginx需要配置开启ngx_status.但是我这边nginx安 ...

  6. Java基础语法05-面向对象-封装-包-构造器-初始化

    封装 面向对象三大特性:封装.继承.多态 封装的好处 1.调用者:方便使用/简化使用 2.设计者:安全,可控 隐藏对象内部的复杂性,只对外公开简单的接口.便于外界调用,从而提高系统的可扩展性.可维护性 ...

  7. 大数据环境下mongoDB要加索引

    mongodb在存储大数据时,对查询的字段需要添加索引,我测试的是阿里云30多万的数据量,不加索引查询已经到8秒,而添加索引之后是毫秒级! 为集合加索引 mongodb支持内嵌属性添加索引 db.ag ...

  8. Goland快捷键(Macbook)

    Goland快捷键(Macbook) 基础编辑快键键 向上或向下移动当前行 ⇧⌘↑ ⇧⌘↓ 复制并粘贴当前选中的语句 ⌘D 删除当前行 ⌘⌫ 行注释 ⌘/ 块注释 ⌥⌘/ 在当前打开的文件中寻找 ⌘F ...

  9. maven配置多个镜像

    问题场景 1.国内访问maven默认远程中央镜像特别慢 2.用阿里的镜像替代远程中央镜像 3.大部分jar包都可以在阿里镜像中找到,部分jar包在阿里镜像中没有,需要单独配置镜像 解决方案 setti ...

  10. Oracle11G_R2中共享服务器模式和专用服务器模式参数解释及设置

    sys@MYTESTDB> show parameterNAME TYPE VALUE------------------------------------ ----------- ----- ...