当前位置:
首页
文章
前端
详情

React Native图片加载

一、静态图片资源

React Native 提供了一个统一的方式来管理 iOS 和 Android 应用中的图片。要往 App 中添加一个静态图片,只需把图片文件放在代码文件夹中某处,然后像下面这样去引用它:

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

图片文件的查找会和 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} />;

二、静态的非图片资源

上面描述的require语法也可以用来静态地加载你项目中的声音、视频或者文档文件。大多数常见文件类型都支持,包括.mp3, .wav, .mp4, .mov, .htm.pdf等(完整列表请看 packager defaults)。

需要注意的是视频必须指定尺寸而不能使用flex样式,因为我们目前还不能从非图片资源中获取到尺寸信息。对于直接链接到 Xcode 或者 Android 资源文件夹的视频,则不会有这个限制。

三、混合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 }}
/>

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

四、网络图片

与静态资源不同的是,你需要手动指定图片的尺寸。强烈建议你使用 https 以满足 iOS App Transport Security 的要求。

// 正确
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
       style={{width: 400, height: 400}} />

传参方式:

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

五、Uri 数据图片

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

建议仅对非常小的图片使用 base64 数据,比如一些小图标。

六、背景图片

return (
  <ImageBackground source={...} style={{width: '100%', height: '100%'}}>
    <Text>Inside</Text>
  </ImageBackground>
);

七、缓存控制(仅 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 }}
/>

免责申明:本站发布的内容(图片、视频和文字)以转载和分享为主,文章观点不代表本站立场,如涉及侵权请联系站长邮箱:xbc-online@qq.com进行反馈,一经查实,将立刻删除涉嫌侵权内容。