图片
静态图片资源
React Native 提供了一种统一的方式来管理你的 Android 和 iOS 应用中的图片和其他媒体资源。要向你的应用添加静态图片,请将其放置在你的源代码树中的某个位置,并像这样引用它
<Image source={require('./my-icon.png')} />
图片名称的解析方式与 JS 模块的解析方式相同。在上面的示例中,打包器将在与需要它的组件相同的文件夹中查找 my-icon.png
。
你可以使用 @2x
和 @3x
后缀为不同的屏幕密度提供图像。如果你有以下文件结构
.
├── button.js
└── img
├── check.png
├── check@2x.png
└── check@3x.png
...并且 button.js
代码包含
<Image source={require('./img/check.png')} />
...打包器将打包并提供与设备屏幕密度相对应的图像。例如,[email protected]
将在 iPhone 7 上使用,而 [email protected]
将在 iPhone 7 Plus 或 Nexus 5 上使用。如果没有与屏幕密度匹配的图像,则将选择最接近的最佳选项。
在 Windows 上,如果你向项目中添加新图像,可能需要重启打包器。
以下是你获得的一些好处
- Android 和 iOS 上相同的系统。
- 图片与你的 JavaScript 代码位于同一文件夹中。组件是自包含的。
- 没有全局命名空间,即你无需担心名称冲突。
- 只有实际使用的图像才会被打包到你的应用中。
- 添加和更改图像不需要重新编译应用,你可以像平常一样刷新模拟器。
- 打包器知道图像尺寸,无需在代码中重复。
- 图像可以通过 npm 包分发。
为了使其工作,require
中的图像名称必须是静态已知的。
// GOOD
<Image source={require('./my-icon.png')} />;
// BAD
const icon = this.props.active
? 'my-icon-active'
: 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />;
// GOOD
const icon = this.props.active
? require('./my-icon-active.png')
: require('./my-icon-inactive.png');
<Image source={icon} />;
请注意,以这种方式要求的图像源包含 Image 的尺寸(宽度、高度)信息。如果你需要动态缩放图像(即通过 flex),你可能需要在 style 属性上手动设置 {width: undefined, height: undefined}
。
静态非图片资源
上面描述的 require
语法也可以用于静态地将音频、视频或文档文件包含在你的项目中。支持最常见的文件类型,包括 .mp3
、.wav
、.mp4
、.mov
、.html
和 .pdf
。有关完整列表,请参阅 打包器默认值。
你可以通过在你的 Metro 配置中添加 assetExts
解析器选项来添加对其他类型的支持。
一个需要注意的是,视频必须使用绝对定位而不是 flexGrow
,因为当前未传递非图像资源的大小信息。对于直接链接到 Xcode 或 Android 的 Assets 文件夹中的视频,不会出现此限制。
来自混合应用资源的图片
如果你正在构建混合应用(一些 UI 在 React Native 中,一些 UI 在平台代码中),你仍然可以使用已捆绑到应用中的图片。
对于通过 Xcode 资源目录或 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}}
/>
这些方法不提供安全检查。你需要保证这些图像在应用程序中可用。此外,你必须手动指定图像尺寸。
网络图片
你将在应用中显示的许多图片在编译时不可用,或者你希望动态加载一些图片以减小二进制文件大小。与静态资源不同,你需要手动指定图像的尺寸。强烈建议你也使用 https,以便满足 iOS 上的 App Transport Security 要求。
// GOOD
<Image source={{uri: 'https://reactjs.ac.cn/logo-og.png'}}
style={{width: 400, height: 400}} />
// BAD
<Image source={{uri: 'https://reactjs.ac.cn/logo-og.png'}} />
网络图片请求
如果你想为图像请求设置 HTTP-Verb、Headers 或 Body 等内容,你可以通过在 source 对象上定义这些属性来实现
<Image
source={{
uri: 'https://reactjs.ac.cn/logo-og.png',
method: 'POST',
headers: {
Pragma: 'no-cache',
},
body: 'Your Body goes here',
}}
style={{width: 400, height: 400}}
/>
URI Data Images
有时,你可能会从 REST API 调用中获取编码的图像数据。你可以使用 'data:'
URI 方案来使用这些图像。与网络资源相同,你需要手动指定图像的尺寸。
建议仅用于非常小的和动态的图像,例如 DB 列表中的图标。
// include at least width and height!
<Image
style={{
width: 51,
height: 51,
resizeMode: 'contain',
}}
source={{
uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==',
}}
/>
缓存控制
在某些情况下,你可能只想在图像已在本地缓存中时才显示图像,例如,在更高分辨率可用之前显示低分辨率占位符。在其他情况下,你不在乎图像是否已过时,并且愿意显示过时的图像以节省带宽。cache
源属性使你可以控制网络层与缓存的交互方式。
default
:使用原生平台的默认策略。reload
:URL 的数据将从原始来源加载。不应使用现有的缓存数据来满足 URL 加载请求。force-cache
:将使用现有的缓存数据来满足请求,无论其存在时间或过期日期如何。如果缓存中没有与请求对应的现有数据,则数据将从原始来源加载。only-if-cached
:将使用现有的缓存数据来满足请求,无论其存在时间或过期日期如何。如果缓存中没有与 URL 加载请求对应的现有数据,则不会尝试从原始来源加载数据,并且加载将被视为失败。
<Image
source={{
uri: 'https://reactjs.ac.cn/logo-og.png',
cache: 'only-if-cached',
}}
style={{width: 400, height: 400}}
/>
本地文件系统图片
有关使用 Images.xcassets
外部的本地资源的示例,请参阅 CameraRoll。
Drawable 资源
Android 支持通过 xml
文件类型加载 drawable 资源。这意味着你可以使用 矢量 drawable 来渲染图标,或使用 形状 drawable 来绘制形状!你可以像使用任何其他 静态资源 或 混合资源 一样导入和使用这些资源类型。你必须手动指定图像尺寸。
对于与你的 JS 代码并存的静态 drawable,请使用 require
或 import
语法(两者工作方式相同)
<Image
source={require('./img/my_icon.xml')}
style={{width: 40, height: 40}}
/>
对于包含在 Android drawable 文件夹(即 res/drawable
)中的 drawable,请使用不带扩展名的资源名称
<Image
source={{uri: 'my_icon'}}
style={{width: 40, height: 40}}
/>
drawable 资源与其他图像类型之间的一个主要区别是,必须在 Android 应用程序的编译时引用该资源,因为 Android 需要运行 Android 资源打包工具 (AAPT) 来打包该资源。二进制 XML(AAPT 创建的文件格式)无法通过 Metro 通过网络加载。如果你更改资源的目录或名称,则每次都需要重建 Android 应用程序。
创建 XML drawable 资源
Android 在其 Drawable resources 指南中提供了有关每种受支持的 drawable 资源类型的全面文档,以及原始 XML 文件的示例。你可以使用 Android Studio 中的工具,如 Vector Asset Studio,从可缩放矢量图形 (SVG) 和 Adobe Photoshop 文档 (PSD) 文件创建矢量 drawable。
最佳相机胶卷图像
iOS 在你的相机胶卷中为同一图像保存多个尺寸,出于性能原因,选择尽可能接近的尺寸非常重要。你不会想在使用 200x200 缩略图作为源时使用全质量 3264x2448 图像。如果存在完全匹配的尺寸,React Native 将选择它,否则它将使用至少大 50% 的尺寸,以避免从接近的尺寸调整大小时出现模糊。所有这些都是默认完成的,因此你无需担心编写繁琐(且容易出错)的代码来自己完成它。
为什么不自动调整所有尺寸?
在浏览器中,如果你不给图像指定尺寸,浏览器将渲染一个 0x0 元素,下载图像,然后使用正确的尺寸渲染图像。此行为的最大问题是,你的 UI 会在图像加载时跳来跳去,这会带来非常糟糕的用户体验。这称为 累积布局偏移。
在 React Native 中,有意未实现此行为。开发者提前知道远程图像的尺寸(或宽高比)会更加费力,但我们相信这会带来更好的用户体验。通过 require('./my-icon.png')
语法从应用包中加载的静态图像可以自动调整大小,因为它们的尺寸在挂载时立即可用。
例如,require('./my-icon.png')
的结果可能是
{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573}
Source 作为对象
在 React Native 中,一个有趣的决定是将 src
属性命名为 source
,并且不接受字符串,而是接受带有 uri
属性的对象。
<Image source={{uri: 'something.jpg'}} />
在基础设施方面,原因是它允许我们将元数据附加到此对象。例如,如果你正在使用 require('./my-icon.png')
,那么我们会添加有关其实际位置和大小的信息(不要依赖此事实,它将来可能会更改!)。这也是面向未来的,例如,我们可能希望在某个时候支持 sprites,而不是输出 {uri: ...}
,我们可以输出 {uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}
,并在所有现有调用站点上透明地支持 spriting。
在用户方面,这使你可以在对象上注释有用的属性,例如图像的尺寸,以便计算它将显示的尺寸。随意使用它作为你的数据结构来存储有关你的图像的更多信息。
通过嵌套实现背景图像
来自熟悉 Web 的开发者的常见功能请求是 background-image
。要处理此用例,你可以使用 <ImageBackground>
组件,该组件具有与 <Image>
相同的 props,并向其添加你想要在其顶部图层的任何子组件。
在某些情况下,你可能不想使用 <ImageBackground>
,因为实现是基本的。有关更多见解,请参阅 <ImageBackground>
的 文档,并在需要时创建你自己的自定义组件。
return (
<ImageBackground source={...} style={{width: '100%', height: '100%'}}>
<Text>Inside</Text>
</ImageBackground>
);
请注意,你必须指定一些宽度和高度样式属性。
iOS 边框半径样式
请注意,以下特定于角的边框半径样式属性可能会被 iOS 的图像组件忽略
borderTopLeftRadius
borderTopRightRadius
borderBottomLeftRadius
borderBottomRightRadius
Off-thread Decoding
图像解码可能需要超过一帧的时间。这是 Web 上帧丢失的主要来源之一,因为解码是在主线程中完成的。在 React Native 中,图像解码是在不同的线程中完成的。在实践中,你已经需要处理图像尚未下载的情况,因此在解码时多显示几帧占位符不需要任何代码更改。
配置 iOS 图像缓存限制
在 iOS 上,我们公开了一个 API 来覆盖 React Native 的默认图像缓存限制。这应该从你的原生 AppDelegate 代码中调用(例如,在 didFinishLaunchingWithOptions
中)。
RCTSetImageCacheLimits(4*1024*1024, 200*1024*1024);
参数
名称 | 类型 | 必需 | 描述 |
---|---|---|---|
imageSizeLimit | number | 是 | 图像缓存大小限制。 |
totalCostLimit | number | 是 | 总缓存成本限制。 |
在上面的代码示例中,图像大小限制设置为 4 MB,总成本限制设置为 200 MB。