React native

Images

Images

静态图像资源

React Native提供了在iOS和Android应用程序中管理图像和其他媒体资源的统一方式。要将静态图像添加到您的应用程序中,请将其放置在源代码树中的某处,并像下面这样引用它:

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

图像名称的解析方式与解析JS模块的方式相同。在上面的示例中,打包程序将my-icon.png在与需要它的组件相同的文件夹中查找。另外,如果你有my-icon.ios.pngmy-icon.android.png,包装者将挑选为平台正确的文件。

您也可以使用@2x@3x后缀为不同的屏幕密度提供图像。如果你有以下文件结构:

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

...和button.js代码包含:

<Image source={require('./img/check.png')} />

...包装商将捆绑并提供与设备的屏幕密度相对应的图像。例如,check@2x.png将在iPhone 7上使用,而check@3x.png在iPhone 7 Plus或Nexus 5上使用。如果没有与屏幕密度相匹配的图像,则会选择最接近的最佳选项。

在Windows上,如果向项目添加新图像,则可能需要重新启动打包程序。

以下是您获得的一些好处:

  • iOS和Android上的系统相同。

  • 图像与您的JavaScript代码位于同一个文件夹中。组件是独立的。

  • 没有全局命名空间,即你不必担心名称冲突。

  • 只有实际使用的图像才会打包到您的应用中。

  • 添加和更改图像不需要重新编译应用程序,只需像通常那样刷新模拟器即可。

  • 包装商知道图像尺寸,不需要在代码中复制它。

  • 图像可以通过npm包分发。

为了这个工作,图像名称require必须是静态的。

// GOOD <Image source={require('./my-icon.png')} /> // BAD var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive'; <Image source={require('./' + icon + '.png')} /> // GOOD var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png' <Image source={icon} />

请注意,以这种方式需要的图像源包括图像的大小(宽度,高度)信息。如果您需要动态缩放图像(即通过flex),则可能需要手动设置{ width: undefined, height: undefined }style属性。

静态非图像资源

require上面描述的语法也可以用于在项目中静态地包含音频,视频或文档文件。最常见的文件类型的支持,包括.mp3.wav.mp4.mov.html.pdf。请参阅完整列表的包装商默认值。

您可以通过创建包装程序配置文件来添加对其他类型的支持(请参阅包装配置文件以获取配置选项的完整列表)。

需要注意的是,视频必须使用绝对定位而不是flexGrow,因为尺寸信息当前未传递给非图像资产。对于直接链接到Xcode或Android资产文件夹的视频,不会出现此限制。

来自混合应用资源的图像

如果您正在构建混合应用程序(React Native中的某些UI,平台代码中的某些UI),则仍然可以使用已捆绑到应用程序中的图像。

对于通过Xcode资产目录或Android可绘制文件夹包含的图像,请使用不带扩展名的图像名称:

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

对于Android资产文件夹中的图片,请使用该asset:/方案:

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

这些方法不提供安全检查。您应该确保这些图像在应用程序中可用。你也必须手动指定图像尺寸。

网络图像

您在应用中显示的许多图像在编译时将不可用,或者您需要动态加载一些图像以保持二进制大小。与静态资源不同,您需要手动指定图像的尺寸。强烈建议您也使用https以满足iOS上的应用传输安全性要求。

// GOOD <Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} style={{width: 400, height: 400}} /> // BAD <Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} />

网络请求图像

如果您想要将HTTP-Verb,Headers或Body与图像请求一起设置,可以通过在源对象上定义这些属性来执行此操作:

<Image source={{ uri: 'https://facebook.github.io/react/img/logo_og.png', method: 'POST', headers: { Pragma: 'no-cache' }, body: 'Your Body goes here' }} style={{width: 400, height: 400}} />

Uri数据图像

有时,您可能会从REST API调用中获取编码的图像数据。您可以使用'data:'uri方案来使用这些图像。与网络资源相同,您需要手动指定图像的尺寸

这仅适用于非常小的动态图像,例如数据库列表中的图标。

// include at least width and height! <Image style={{width: 51, height: 51, resizeMode: Image.resizeMode.contain}} source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}/>

缓存控制(仅适用于iOS)

在某些情况下,如果图像已经存在于本地缓存中,您可能只想显示一幅图像,也就是说,一个低分辨率的占位符,直到有更高的分辨率可用。在其他情况下,您不在乎图像是否过时,并且愿意显示过时的图像以节省带宽。在cache源属性为您提供了网络层和缓存交互控制。

  • default:使用本机平台默认策略。

  • reload:URL的数据将从原始来源加载。不应该使用现有的缓存数据来满足URL加载请求。

  • force-cache:现有的缓存数据将用于满足请求,无论其年龄或到期日期如何。如果高速缓存中没有对应该请求的现有数据,则从源数据源加载数据。

  • only-if-cached:现有的缓存数据将用于满足请求,无论其年龄或到期日期如何。如果高速缓存中没有与URL加载请求相对应的现有数据,则不会尝试从源数据源加载数据,并认为加载失败。

<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png', cache: 'only-if-cached'}} style={{width: 400, height: 400}} />

本地文件系统映像

有关使用本地资源以外的示例,请参阅CameraRoll Images.xcassets

最佳相机胶卷图像

iOS会在相机胶卷中为同一图像保存多种尺寸,因此出于性能原因选择尽可能接近相机的图像非常重要。显示200x200缩略图时,您不希望将全质量3264x2448图像用作来源。如果有完全匹配,则React Native会选择它,否则它将使用至少大50%的第一个,以避免从缩小尺寸调整大小时产生模糊。所有这些都是默认完成的,因此您不必担心编写繁琐(容易出错)的代码来自行完成。

为什么不自动调整大小?

在浏览器中,如果您不给图片的大小,浏览器将呈现0x0元素,下载图片,然后基于正确的大小呈现图片。这种行为的一个大问题是,随着图像加载,您的用户界面会四处跳跃,这会导致非常糟糕的用户体验。

在React Native中,这种行为是故意没有实现的。提前了解远程图像的尺寸(或宽高比)对于开发人员来说是更多的工作,但我们相信它会带来更好的用户体验。通过require('./my-icon.png')语法从应用程序包加载的静态图像可以自动调整大小,因为它们的尺寸在安装时立即可用。

例如,结果require('./my-icon.png')可能是:

{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573}

源作为对象

在React Native中,一个有趣的决定是该src属性被命名source并且不接受字符串,而是具有uri属性的对象。

<Image source={{uri: 'something.jpg'}} />

在基础设施方面,原因是它允许我们将元数据附加到此对象。例如,如果您正在使用require('./my-icon.png'),那么我们会添加有关其实际位置和大小的信息(不要依赖这个事实,它可能会在将来更改!)。这也是未来的证明,例如我们可能希望在某些时候支持精灵,而不是输出{uri: ...},我们可以输出{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}并透明地支持所有现有呼叫站点的精灵。

在用户方面,这可以让您使用有用的属性(例如图像的尺寸)为对象注释对象,以便计算将要显示的尺寸。请随意将其用作数据结构以存储有关图像的更多信息。

背景图像通过嵌套

熟悉网络的开发人员提出的共同要求是background-image。为了处理这个用例,你可以使用这个<ImageBackground>组件,它具有相同的道具<Image>,并添加你想要在其之上层叠的任何子项。

你可能不想<ImageBackground>在某些情况下使用,因为实现非常简单。请参阅<ImageBackground>的源代码进行更深入的了解,并在需要时创建自己的自定义组件。

return ( <ImageBackground source={...}> <Text>Inside</Text> </ImageBackground>

iOS边框半径样式

请注意,iOS的图像组件目前忽略了以下特定角落边框半径样式属性:

  • borderTopLeftRadius

  • borderTopRightRadius

  • borderBottomLeftRadius

  • borderBottomRightRadius

脱机解码

图像解码花费的时间可能不止一帧。这是网络上丢帧的主要来源之一,因为解码是在主线程中完成的。在React Native中,图像解码是在不同的线程中完成的。实际上,当图像尚未下载时,您已经需要处理这种情况,因此在解码时将占位符显示多一些帧并不需要更改代码。