Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React Native与Iconfont #15

Open
MrErHu opened this issue Jun 26, 2017 · 7 comments
Open

React Native与Iconfont #15

MrErHu opened this issue Jun 26, 2017 · 7 comments

Comments

@MrErHu
Copy link
Owner

MrErHu commented Jun 26, 2017

  之前总是想写一些关于学习体会和感受的文章,今天也来一篇关于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,有需要的同学可以参考一下。

@jayce712
Copy link

请问一下,那个import glyphMap from './Iconfont.json'中的Iconfont.json文件怎么生成的?从IconFont下载的并没有这个json文件啊~要自己手动生成?

@MrErHu
Copy link
Owner Author

MrErHu commented Jun 27, 2017

@Lockie-cn 确实是这样的,Iconfont.json是图标key=>value的关系对应表,其中key值是你自己定义的,只要是唯一的就可以。value对应的是图标库里面的编码,以阿里巴巴适量图标库为例,
其中的十六进制unicode值就是你应该对应的value,但是需要将十六进制转化成十进制。

@349989153
Copy link

其实正确添加了iconfont.tff,好像可以很简便的用iconfont。
http://gehaiqing.com/blog/2017/02/22/20170222-react-native-iconfont/

但关键是我现在试用了各种方法各种姿势,依然只能得到一个报错:
Unrecognized font family 'iconfont'

@MackYang
Copy link

我在使用过程中发现一个很不爽的问题,
在iconfont.ttf中添加了新的自定义图标后,
必须react-native run-android 重新生成APK才能显示出来,
这就导致了自定义的图标不能进行热更新,每次都要发新的APK包,这样操作很麻烦,
不知道大神们有没有什么办法解决...

@OliveKong
Copy link

自定义的配置文件是写在 react-native-vector-icons里(和自带的配置文件写在一个文件夹中)呢,还是写在别的地方呢,另外unicode怎么变成10进制呢

@hoozi
Copy link

hoozi commented Jul 11, 2018

MARK

@samwangdd
Copy link

Mark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants