10

  之前总是想写一些关于学习体会和感受的文章,今天也来一篇关于React Native的教程文章。前段时间我尝试着用React Native构建一个论坛的APP,在这个过程中遇见一个问题: 最开始我是用图片的形式去构建APP中的图标,但用图片构建图标的过程中会遇到一个问题,就是图片的加载速度非常之慢,APP页面加载过程中图标会出现留白的情况,所以我就想要用Iconfont去构建图标。

Iconfont

  Iconfont,如字面的意思,就是字体图标。如果你身处在一个视觉或者交互对页面UI一天一变的蛋疼团队,你会深刻的理解使用图片作为图标的不便之处:

  1. 图标大小会变化,当然你可以通过设置的图片大小去改变图标。但是如果你开始使用的图片的分辨率较低的话,放大图标会造成图标的失真。当然你可以一开始就选择一个高分辨率的图片,但是高分辨的图片会造成加载速度减慢。

  2. 图标的颜色会变化,假如一开始视觉要求红色的图标,明个脑子一抽风,又要求蓝色的图片。这时候如果你用的是图片,没别的办法,只能换新的图片。

  3. 图标本身也会变化,今天视觉觉得圆的图标好看,明个觉得方的图标好看,咱又得辛辛苦苦替换图片或者改变图片的应用路径。

  有了Iconfont一切就不一样了:

  1. Iconfont中字体图标都是矢量的,你可以像设置字体大小一样,放大或缩小并且保证不失真。

  2. Iconfont中字体图标同字体相同,可以通过设置颜色属性改变图标颜色。

  3. Iconfont字体图标制作简单,并且目前有相当多的线上图标库和制作图标Iconfont的站点。只要上传svg的图标设计稿,就能线上生成iconfont字体文件,而且连使用代码都直接生成。

  4. Iconfont字体图标具有非常好的兼容性,甚至在IE6中都可以使用。

React Native中使用Iconfont

  说了Iconfont这么多的好处,现在我们就尝试着在React Native中使用Iconfont。作为Github的搬运工,想要在React Native中使用Iconfont我们需要使用库:react-native-vector-icons,
react-native-vector-icons 使得React Native支持自定义的图标库,并支持NavBar/TabBar/ToolbarAndroid等控件与图片形式的图标以及各种样式。其主要优点有:

  • 你可以使用自定义的图标库,支持SVG和常规的Iconfont

  • 可以在原生的TabBarIOS中使用

  • 你可以在Text组件中像使用emojis表情一样或者在按钮中使用图标

  • 如果原生的组件需要的是一个Image(例如:NavigatorIOS),你可以像使用一个Image一样使用Icon

  • 大多数情况下是在JavaScript中使用,因此可以非常灵活的定制样式并且很方便地集成进现有的项目中

  • 不需要定义heightwidth

  • 可以在样式表中定义类似sizecolor的属性,而不是通过属性去定义

  react-native-vector-icons内置了很多字体图标,譬如:

   当然我们希望能够支持我们自定义Iconfont。下面逐步介绍如果在React Native中使用Iconfont。

  首先,下载相应的Iconfont文件(*.ttf),我们在阿里巴巴矢量图标库中新建一个项目,将所需要的图标都保存到该项目中,并下载到本地。

  我们通过react-native init的方式初始化一个React Native项目,在其中新建一个assets目录,其中再建一个font的文件夹来存储字体文件。我们的项目是在iOS中开发的,首先在iOS进行相应的系统配置。项目目录如下图所示:

iOS配置

  react-native-vector-icons支持相当多的内置字体库,但要使用内置字体库,也需要进行如下的配置,所有的内置字体库文件都在node_modules/react-native-vector-icons中的Fonts文件夹下。我们以刚才下载的Iconfont.ttf为例,我们将其复制进assets/font文件夹下。然后我们用Xcode
打开ios目录下*.xcodeproj项目配置文件。如下图所示:

  我们在目录下新建Fonts文件夹(非必须),并将assets/font中的Iconfont.ttf拖拽进工程配置中的Fonts文件夹,切记!一定要是在Xcode中拖拽进该目录,如果是拖拽进Xcode中时,我们会看见下面的对话框,

我们选择Create groups并按照需求选择多选项,我们只需要在iOS中使用,就只选择第一项就可以。然后我们打开(项目名)Guides下的Info.plist文件。

  然后我们在Information property list下新建Fonts provided by application属性,并配置Iconfont.ttf,如下图所示:

Android配置

  Android的配置相对比较简单,如果只想使用在react-native-vector-icons中内置的图标,只需要在项目中android/app/build.gradle目录下增加:

apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

  对于自定义的图标库,也只需要在android/app/build.gradle中添加:


project.ext.vectoricons = [
    iconFontNames: ['Iconfont.ttf' ] //添加你需要赋值的字符文件
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

使用方法

Icon Component

  如果是内置图标库中图标,你可以通过如下方式使用:

import Icon from 'react-native-vector-icons/FontAwesome';
const myIcon = (<Icon name="rocket" size={30} color="#900" />)

  对于自定义图标库,我们可以参考一下FontAwesome是怎么设计的:


/**
 * FontAwesome icon set component.
 * Usage: <FontAwesome name="icon-name" size={20} color="#4F8EF7" />
 */

import createIconSet from './lib/create-icon-set';
import glyphMap from './glyphmaps/FontAwesome.json';

const iconSet = createIconSet(glyphMap, 'FontAwesome', 'FontAwesome.ttf');

export default iconSet;

export const Button = iconSet.Button;
export const TabBarItem = iconSet.TabBarItem;
export const TabBarItemIOS = iconSet.TabBarItemIOS;
export const ToolbarAndroid = iconSet.ToolbarAndroid;
export const getImageSource = iconSet.getImageSource;

  而FontAwesome.json中代码如下

{
  "glass": 61440,
  "music": 61441,
  "search": 61442,
  "envelope-o": 61443,
  "heart": 61444,
  "star": 61445,
  "star-o": 61446,
  "user": 61447,
  //等等...
}

  这样一看使用方法也是非常地简单,综合上述代码,我们首先介绍一下其中的API:

createIconSet(glyphMap, fontFamily[, fontFile])

返回基于glyphMap的自定义字体集,其中key是图标的名字,值可以是UTF-8字符,也可以是字符编码(需要注意的是,glyphMap配置文件中的value需要是十进制,如果字体库中提供的是十六进制编码,那么就需要将十六进制转换成十进制数)。fontFamily不是文件名。fontFile参数是可选的,其目的是支持安卓系统,应该是资源目录下的地址。

那么非常简单,我们也可以编写一个我们自定义的图标组件:

import createIconSet from 'react-native-vector-icons/lib/create-icon-set';
import glyphMap from './Iconfont.json';

const iconSet = createIconSet(glyphMap, 'Iconfont', 'Iconfont.ttf');

export default iconSet;

最后的效果如下:

  不仅如此,我们还可以在Icon中使用Text组件,

<Icon.Button name="facebook" backgroundColor="#3b5998">
    <Text style={{fontFamily: 'Arial', fontSize: 15}}>Login with Facebook</Text>
</Icon.Button>

从而做出如下的效果:

  react-native-vector-icons还有其他的用法,这里只是抛砖迎玉,不再啰嗦,有兴趣大家可以到Github中仔细阅读一下文档。本文章的代码地址如下React-Native-Vector-Icons-Guides,有需要的同学可以参考一下。


请叫我王磊同学
1.1k 声望169 粉丝

编程新人