从0.14 版本开始,React Native 就提供了一种统一方式来管理 iOS 和 Android 应用的图片。
你可以将静态图片资源添加到你的代码目录的某个地方,然后通过下面这种方式引用:
<Image source={require('./my-icon.png')} />
图片文件会被以 JS 模块查找的方式来查找。在上面这个列子中,Packager就会去这个组件所在的文件夹下查找my-icon.png。并且,如果你有my-icon.ios.png和my-icon.android.png,Packager就会根据平台而选择不同的文件。
关于 React Native 中的 Packager,官方的说法是:
React Native Packager is a project similar in scope to browserify or webpack, it provides a CommonJS-like module system, JavaScript compilation (ES6, Flow, JSX), bundling, and asset loading.
The main difference is the Packager's focus on compilation and bundling speed. We aim for a sub-second edit-reload cycles. Additionally, we don't want users -- with large code bases -- to wait more than a few seconds after starting the packager.
首先理解下什么是混合App,这里的不是 iOS 和 Android 代码复用,而是 React Native 和原生代码的混合。
官网上的说法是:
a hybrid app (some UIs in React Native, some UIs in platform code)
也就是说,在这个 App 中部分 UI 使用 React Native,而另一部分使用各原生原生的代码。
编写一个混合App,可以使用已经打包(通过 Xcode 的 asset 类目或者 Android 的 drawable 文件夹打包)到 App 中的图片资源。使用方式如下:
<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />
需要注意的是,这种方式没有做安全检查,你需要自己确保图片在应用中是确实存在的,同时,需要指定图片的宽高
有一些需要在 APP 中展示的图片在编译时期还不能获取,或者你想要通过动态加载图片的方式来减少二进制文件的大小。
这里与静态图片有一点区别,你需要手动指定这些图片的尺寸。(关于什么时候需要指定图片尺寸,在下面有讨论)
// 正确
<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
style={{width: 400, height: 400}} />
这个暂时不做讨论
官网上说的很多,我总结一下就是:
为了避免像浏览器中,如果不指定图片尺寸,UI 在图片加载过程中会跳动的问题。
在 React Native 中,从应用包中通过require('./my-icon.png')
语法加载的静态图片则无需指定尺寸,因为它们的尺寸在加载时就可以立刻知道。
因为,通过require('./my-icon.png')
加载时,实际上输出的结果可能是:
{"__packager_asset":true,"path":"/Users/react/HelloWorld/my-icon.png","uri":"my-icon.png","width":591,"height":573}
也就是说,直接输出了图片的实际尺寸,绝对路径等信息。
在 React Native 中,原本图片标签中的 src 属性 变成了 source ,并且 source 不是作为一个字符串而是作为一个包含 uri 属性的对象而存在。
为什么 React Native 这么处理呢?
因为 React Native 一直在持续的开发,为了方便以后扩展,比如,将来可能通过 {uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}
的方式来支持"雪碧图"。
从用户角度来说,通过这样的数据结构可以获取到更多有关该图片的信息。
可以通过在 Image 组件中嵌套子组件的方式来实现背景图,示例如下:
return (
<Image source={...}>
<Text>Inside</Text>
</Image>
);
相关文章推荐: