在React Native中使用SVG-教程与示例

9,232 阅读8分钟

当你在开发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导入SvgCircle 组件,如下图所示。

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, 和viewBoxviewBox 道具描述了你的SVG在空间中的定位方式。heightwidth 道具是不言自明的。

<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> 组件将xy 坐标分别作为cxcy 的道具。这些坐标定义了你的SVG组件在容器中的定位方式和位置。如果你要渲染一个不同的SVG形状,比如说一个矩形,同样会分别用xy 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圆,如下图所示。

React Native SVG Circle Shape Example

注意,我把<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,如下图所示。

React Native SVG Icon Example

<SvgUri> 你可以使用widthheight 组件的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了。

React Native SVG Homer Simpson Example

总结

SVG对于渲染你想在React Native应用中使用的图片和图标来说是非常好的。你甚至可以用它们来创建复杂的形状和图案,为你的应用程序的设计增添更多的美感。

记住,在本地存储大量的SVG文件仍然会使你的应用程序变得臃肿。你应该始终避免在你的项目中保存大量的SVG文件并在本地引用它们。如果你绝对有必要,你可以使用这个方便的工具来优化你的SVG文件。

我希望这个教程能让你更容易在你的React Native项目中使用SVG。你也可以探索和玩玩react-native-svg官方文档中说明的例子。