当你在开发React Native应用程序时,你可能会被要求实现图标。现在,简单的方法是简单地提取图标的.png 或.jpeg 文件,并在React Native的Image 组件中使用它。这将为你带来好处,但你不会得到清晰的质量,而且你最终会用更高的图像文件大小来膨胀你的应用程序,这将增加你的应用程序捆绑大小。
你不应该在你的React Native应用中使用.png 或.jpeg 文件,而应该使用SVG格式。SVG是一种基于矢量的格式,可以无限扩展而不影响质量。
在本指南中,我们将演示如何使用react-native-svg 库在你的React Native应用中实现SVG图标。
我们将通过实际例子介绍以下内容。
什么是可扩展矢量图(SVG)?
SVG是一种基于XML的格式,用于渲染矢量图像。矢量图像可以按照你的要求任意缩放而不出现像素化,因为矢量图像是由数学方程驱动的,不像其他图像格式那样有像素,比如.png 和.jpeg 。
由于SVG格式的矢量性质,图像与分辨率无关。SVG图像在任何屏幕上看起来都很清晰,从新的智能手机上华丽的285DPI像素密度屏幕到标准显示器的85DPI屏幕。与其他图像格式相比,SVG文件的尺寸也很小。
如果你在文本编辑器中打开一个SVG文件,你会看到一个带有数字和各种节点的大型XML代码。在本教程中,我们不会把重点放在SVG本身。相反,我们将演示如何在移动应用屏幕上渲染SVG。
React Native支持SVG吗?
在移动应用中渲染SVG并不像在网络上那样简单,在网络上你可以直接使用SVG作为图片源,或者将SVG代码粘贴到你的HTML文件中。这是因为没有一个内置的React Native组件可以直接渲染SVG。
由于React Native没有提供对SVG的默认支持,我们必须从npm注册表中安装一些库。幸运的是,有一个流行的npm包,对于大多数的使用情况来说都很好用,叫做react-native-svg。
让我们从建立一个React Native项目开始。运行下面的命令。
npx react-native init SvgDemoApp
要安装 react-native-svg 和react-native-svg-transformer包,进入项目目录并运行以下命令。
cd SvgDemoApp
npm i react-native-svg
npm i --save-dev react-native-svg-transformer
react-native-svg为你在Android和iOS平台上的React Native项目提供SVG支持。 react-native-svg-transformer使你能够在React Native项目中导入本地SVG文件,就像你在网络上的Creact React App项目那样。
如果你使用Expo CLI而不是React Native CLI,你可以通过运行以下命令开始。
expo init SvgDemoApp
expo install react-native-svg
在React Native中渲染SVG形状
让我们看看如何使用react-native-svg库来在你的应用程序中渲染SVG。
在你喜欢的编辑器中打开项目,从react-native-svg导入Svg 和Circle 组件,如下图所示。
import Svg, { Circle } from 'react-native-svg';
<Svg> 组件是一个父级组件,需要它来渲染任何SVG形状。它就像是所有SVG形状的一个容器组件。如果你要渲染任何SVG形状,比如一个圆或一个多边形,你必须用它作为你的SVG组件的一个包装组件。
<Svg height="50%" width="50%" viewBox="0 0 100 100" >
...
</Svg>
<Svg> 组件需要三个道具:height,width, 和viewBox 。viewBox 道具描述了你的SVG在空间中的定位方式。height 和width 道具是不言自明的。
在<Svg> 组件内,渲染<Circle> 组件,如下所示。
<Svg height="50%" width="50%" viewBox="0 0 100 100" >
<Circle cx="50" cy="50" r="50" stroke="purple" strokeWidth=".5" fill="violet" />
</Svg>
<Circle> 组件将x 和y 坐标分别作为cx 和cy 的道具。这些坐标定义了你的SVG组件在容器中的定位方式和位置。如果你要渲染一个不同的SVG形状,比如说一个矩形,同样会分别用x 和y props来表示。
为了描述圆的半径,你可以将一个整数作为字符串传递给r 道具。你可以设置这个值来增加或减少渲染的SVG圆的大小。
stroke 道具可以用来表示SVG元素周围边框的颜色,strokeWidth 表示该边框的厚度。最后,fill 道具表示渲染的SVG元素的颜色。这些道具与本地HTML<svg> 元素上的属性相似,而且在大多数SVG组件中都是通用的。
请看一下在屏幕上渲染SVG圆圈的整个代码。
import React from 'react';
import { StyleSheet, View } from 'react-native';
import Svg, { Circle } from 'react-native-svg';
export default function App() {
return (
<View style={styles.container}>
<Svg height="50%" width="50%" viewBox="0 0 100 100" >
<Circle cx="50" cy="50" r="50" stroke="purple" strokeWidth=".5" fill="violet" />
</Svg>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
你应该看到一个紫色的SVG圆,如下图所示。
注意,我把<Svg> 组件包裹在一个<View> 组件里面。你可以将你的SVG组件包裹在任何通用的容器组件内,比如<View> 或任何其他自定义的包裹组件。这样,你就可以使用Flexbox布局在屏幕上的任何地方放置和定位你的SVG组件,正如上面的例子所演示的那样。
同样,你也可以渲染其他SVG形状,如矩形、多边形、直线、椭圆等。
如何在React Native中渲染SVG图像和图标
现在你已经了解了如何使用react-native-svg库渲染任何SVG,让我们探讨一下如何在你的应用程序中渲染SVG图标和图像。
在这里,你需要使用一个叫做SvgUri 的不同组件,所以让我们从库中导入它。
import { SvgUri } from 'react-native-svg';
<SvgUri> 组件接受width,height, 和uri 道具。你可以指定uri prop指向SVG的URL。例如,如果你想渲染这个 SVG,你可以把这个URL分配给uri ,然后再分配给你的<SvgUri> 组件,如下图所示。
<SvgUri
width="100%"
height="100%"
uri="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/debian.svg"
/>
src 这与在React中渲染图片很相似,你可以指定<img> 的属性作为图片的URL。
上面的代码应该在屏幕上渲染SVG,如下图所示。
<SvgUri> 你可以使用width 和height 组件的props来调整SVG的宽度和高度。与渲染SVG形状时不同,这里你不需要一个容器组件。
你可能会遇到需要引用本地SVG图标或项目内部的图像的情况。当你在设置示例项目时,记得你也安装了库react-native-svg-transformer 。你可以用它来渲染你项目中的本地SVG图标或图片。
首先,你需要对你的项目做一些配置上的改变。前往你的项目的metro.config.js 文件。如果这个文件在你的项目中不存在,你就需要创建它。
然后,在其中添加以下代码。
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts },
} = await getDefaultConfig();
return {
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
},
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg'],
},
};
})();
接下来,下载一个SVG并将其保存在你的项目中,类似于你下载一个你想在项目中使用的图片。假设你把你的SVG文件命名为image.svg 。现在你可以像其他组件一样导入这个SVG文件。
import SVGImg from './image.svg';
并在任何组件中渲染它。
<SVGImg width={200} height={200} />
上面的代码应该在屏幕上渲染相同的SVG。如果你的项目要求你在本地渲染SVG图标,你可以按照这个方法在你的应用程序中渲染不同的SVG图标。
使用XML字符串渲染SVG
在少数情况下,如果你无法使用<SvgUri> 组件引用本地SVG,你可以使用XML字符串在React Native应用中渲染SVG。
假设你已经在你的项目中下载了这个SVG文件。如果你进入这个SVG文件内部,你会注意到一堆XML代码,其中有一个<svg> HTML元素。你可以使用<SvgXml> 组件从其XML代码中直接渲染一个SVG。
import { SvgXml } from 'react-native-svg';
从SVG文件的XML代码中复制<svg> 元素内的所有内容,并将其存储在一个变量中。
const xml = `
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
...
</svg>
`;
然后,将上述变量传递给你的<SvgXml> 组件中的xml 道具,如下图所示。
<SvgXml xml={xml} width="100%" height="100%" />
然后就可以了!现在你应该在屏幕上看到上面的SVG了。
总结
SVG对于渲染你想在React Native应用中使用的图片和图标来说是非常好的。你甚至可以用它们来创建复杂的形状和图案,为你的应用程序的设计增添更多的美感。
记住,在本地存储大量的SVG文件仍然会使你的应用程序变得臃肿。你应该始终避免在你的项目中保存大量的SVG文件并在本地引用它们。如果你绝对有必要,你可以使用这个方便的工具来优化你的SVG文件。
我希望这个教程能让你更容易在你的React Native项目中使用SVG。你也可以探索和玩玩react-native-svg官方文档中说明的例子。