图片
静态图片资源
React Native 提供了一个统一的方式来管理 iOS 和 Android 应用中的图片。要往 App 中添加一个静态图片,只需把图片文件放在代码文件夹中某处,然后像下面这样去引用它:
<Image source={require('./my-icon.png')} />
注意,一些老文章和教程提到的
require('image!xxx')
的写法已经从 0.40 版本开始不再支持!
图片文件的查找会和 JS 模块的查找方式一样。在上面的这个例子里,是哪个组件引用了这个图片,Packager 就会去这个组件所在的文件夹下查找my-icon.png
。并且,如果你有my-icon.ios.png
和my-icon.android.png
,Packager 就会根据平台而选择不同的文件。
你还可以使用@2x
,@3x
这样的文件名后缀,来为不同的屏幕精度提供图片。比如下面这样的代码结构:
.
├── button.js
└── img
├── check.png
├── check@2x.png
└── check@3x.png
并且button.js
里有这样的代码:
<Image source={require('./img/check.png')} />
Packager 会打包所有的图片并且依据屏幕精度提供对应的资源。譬如说,iPhone 7 会使用check@2x.png
,而 iPhone 7 plus 或是 Nexus 5 上则会使用check@3x.png
。如果没有图片恰好满足屏幕分辨率,则会自动选中最接近的一个图片。
注意:如果你添加图片的时候 packager 正在运行,可能需要重启 packager 以便能正确引入新添加的图片。
这样会带来如下的一些好处:
- iOS 和 Android 一致的文件系统。
- 图片和 JS 代码处在相同的文件夹,这样组件就可以包含自己所用的图片而不用单独去设置。
- 不需要全局命名。你不用再担心图片名字的冲突问题了。
- 只有实际被用到(即被 require)的图片才会被打包到你的 app。
- 现在在开发期间,增加和修改图片不需要重新编译了,只要和修改 js 代码一样刷新你的模拟器就可以了。
- 与访问网络图片相比,Packager 可以得知图片大小了,不需要在代码里再声明一遍尺寸。
- 现在通过 npm 来分发组件或库可以包含图片了。
注意:为了使新的图片资源机制正常工作,require 中的图片名字必须是一个静态字符串(不能使用变量!因为 require 是在编译时期执行,而非运行时期执行!)。
// 正确
<Image source={require('./my-icon.png')} />;
// 错误
const icon = this.props.active
? 'my-icon-active'
: 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />;
// 正确
const icon = this.props.active
? require('./my-icon-active.png')
: require('./my-icon-inactive.png');
<Image source={icon} />;
请注意:通过这种方式引用的图片资源包含图片的尺寸(宽度,高度)信息,如果你需要动态缩放图片(例如,通过 flex),你可能必须手动在 style 属性设置{ width: null, height: null }
。
静态的非图片资源
上面描述的require
语法也可以用来静态地加载你项目中的声音、视频或者文档文件。大多数常见文件类型都支持,包括.mp3
, .wav
, .mp4
, .mov
, .htm
和 .pdf
等(完整列表请看 packager defaults)。
你也可以在metro(即 packager)配置文件中添加assetExts
配置项来支持其他类型的文件。
需要注意的是视频必须指定尺寸而不能使用flex
样式,因为我们目前还不能从非图片资源中获取到尺寸信息。对于直接链接到 Xcode 或者 Android 资源文件夹的视频,则不会有这个限制。