最灵活的UI控件库:React Native UI Lib

前言

我从11年开始写Objective-C。记得当时开源的UI控件库还不是很多,最火的可能就是three20nimbus。可惜three20已经有七年不维护了,nimbus也有两年没有更新代码。后来国内著名的BeeFramework在短时间内获得很多的关注度。从QQ空间出来的老郭,做出的CSS代替原生UI开发方式的技术方案,让我眼前一亮。只是因为团队学习成本太大,我最终放弃了在项目中使用BeeFramework。
可能是之前在UI控件库的选择上,栽过跟头,也尝过甜头。我觉得找一个好用且稳定的控件库,对一个项目来说非常重要。所以我从接触React Native开始,就一直在寻找一个适合自己的控件库。中间尝试了三、四个,最后因为种种原因而放弃。直到有一天遇到react-native-ui-lib。简单的技术调研后,我就把所有项目全部替换成这个库。

控件库对比

下面简单分析下使用过的几个库的优缺点:

react-native-elements

优点

  • 关注度高,响应速度快

目前我所知道的UI框架中,star数量最高的。目前(18年2月4日)已经有9142个,而且commit频率很高。大部分已知的bug,很快就会被修复。

  • 控件齐全

提供了一套完善且风格一致的UI控件。如果你们团队的设计师比较认同这套UI,那么恭喜你。你可以使用这个UI框架,在几天内完成一个小型App的UI。

不足

  • 样式修改麻烦

如果你们App的UI定制化程度高,那么恭喜你,你可能需要写比原来更多的UI代码,来对这套UI框架进行定制化开发。所以我在使用这套框架的后期,干脆模仿他们的编码思路,自己定制一套适合项目的基础控件,比如Text、Button、ListItem等。使用他们的控件反而越来越少。

  • 少许的bug

在使用过程中,发现了两三个bug,比如在安卓上textInput显示异常等。不过归功于这个库关注度很高,维护的团队也非常认真,所以issues里基本上都能找到解决方案。

NativeBase

与react-native-elements提供的能力差不多,目前(18年2月4日)star的数量是7586。是我最早使用的一个react native的ui库。只是后来发现bug相对较多,使用起来也没有react-native-elements方便。后来就转向使用react-native-elements。

react-native-ui-lib

优点

  • 快速布局

相较于react-native-elements,react-native-ui-lib最大的优点,就是额外提供了View、Text、Button等基础组件的便捷布局能力。比如下面这个页面的布局


f5db80f4-1b82-11e7-8538-5a3388fb4345.png

你只需要这样写

import React, {Component} from 'react';
import {View, TextInput, Text, Button} from 'react-native-ui-lib';

export default class Example extends Component {

  render() {
    return (
      <View flex paddingH-25 paddingT-120>
        <Text blue50 text20>Welcome</Text>
        <TextInput text50 placeholder="username" dark10/>
        <TextInput text50 placeholder="password" secureTextEntry dark10/>
        <View marginT-100 center>
          <Button text70 white background-orange30 label="Login"/>
          <Button link text70 orange30 label="Sign Up" marginT-20/>
        </View>
      </View>
    );
  }
}

不足

  • 关注度不高

目前(18年2月4日)star的数量是437

  • 文档不全

官网的首页,一直处于开发中的状态。从我关注这个库到现在,已经几个月过去了。不知道wix的团队在忙什么。。。 >.<
API文档也比较粗糙。没有react-native-elements做得全面。

  • 最新版本支持React Native0.44

官方声称目前支持到0.44,不过我在0.52上使用,没有发现什么问题。不确定是否有隐藏比较深的坑。

讲了这么多不足,只是让各位在使用的过程中,有一个心理准备。这些不足并没有阻挡我对这个库的热爱。目前我在使用过程中,还没出现什么问题。如果有发现坑的,欢迎大家在下方留言。

使用介绍

接下来,具体看一下如何使用react-native-ui-lib库(以下简称UILib)

全局的样式配置

如何定义样式,是使用一个UI组件的关键。UILib内置了多种全局样式的配置方式,包括Colors, Typography, Shadows, Border Radius等。

下面的例子中,我们通过接口

Colors.loadColors()

定义两种全局的颜色:pink和gold。

通过接口

Typography.loadTypographies()

定义两种全局的文字样式:h1和h2。

import {Typography, Colors} from 'react-native-ui-lib';

Colors.loadColors({
  pink: '#FF69B4',
  gold: '#FFD700',
});

Typography.loadTypographies({
  h1: {fontSize: 58, fontWeight: '300', lineHeight: 80},
  h2: {fontSize: 46, fontWeight: '300', lineHeight: 64},
});

然后我们就可以在项目的任何地方,非常方便的使用颜色和文字样式了。比如要设置Text的文字样式为h1,颜色为pink,只需要这样写:

<Text h1 pink>Hello World</Text>

最终的效果是这样的


296b7ebc-1b86-11e7-8580-9252d1ddf5d9.png

对我来说,Colors和Typography已经够用了。如果你们想了解更多的全局设置接口,可以查看他们的源码,是的。。。只能看源码了,因为文档并不全面,扎心了老铁。。 T.T

快速对齐

使用UILib提供的几个属性,可以快速的实现内容的对齐。比如下面的代码,使用了View的left、right、top、bottom、center属性。非常方便的设置了内容(这里的Button)的布局。

<View left>
  <Button label="Button">
</View>

<View right>
  <Button label="Button">
</View>

<View top>
  <Button label="Button">
</View>

<View bottom>
  <Button label="Button">
</View>

<View center>
  <Button label="Button">
</View>

最终的效果长这样


image.png

颜色

在上面,我们提到了使用Colors.loadColors()来统一配置颜色。如果我们要设置文字的颜色,可以这样:

<Text pink>...</Text>

如果我们希望把View的背景也设置成pink的话,我们可以这样:

<View bg-pink>...</View>

我们并不需要额外在Colors.loadColors()中设置bg-pink这个key。只需要在我们定义的key前面,加上bg-或者background-就可以了。

flex

如果我们要设置View的flex,我们可以直接这样:

<View flex> // 在这里,flex默认为1
  <View flex-2/>
  <View flex-3/>
  <View flex-4/>
</View>

padding/margin

UILib同样提供了快速设置padding和margin的方法:
padding-[value], paddingL-[value], paddingT-[value], paddingR-[value], paddingB-[value], paddingH-[value], paddingV-[value]
比如,我们想设置View的paddingVertical为20,只需要设置View的属性paddingV,后面加上横杠,然后是具体的数值:

<View paddingV-20>...</View>

如果同时要设置paddingHorizontal为30,只需要这样:

<View paddingV-20 paddingH-30>...</View>

margin的使用方式和padding一样:
margin-[value], marginL-[value], marginT-[value], marginR-[value], marginB-[value], marginH-[value], marginV-[value]
如果要设置View的marginTop为5,marginBottom为10,只需要这样:

<View marginT-5 marginB-10>...</View>

更多的相关接口,可以查看官方接口文档

图片资源的统一管理

图片资源是UI代码里很重要的一个组成部分。包括图标、占位图等。我们在项目的非常多地方,都会使用到资源。UILib提供了一套统一的管理方式,方便我们使用图片资源。
我们可以在App启动时,加载需要用到的图片资源

import {Assets, Image} from 'react-native-ui-lib';

Assets.loadAssetsGroup('icons', {
  icon1: require('icon1.png'),
  icon2: require('icon2.png'),
  icon3: require('icon3.png'),
});

然后在使用Image组件时,通过assetName设置图片

<Image assetName="icon1"/> // 默认情况下,assetGroup属性是"icons"

我们也可以配置自己的AssetsGroup

Assets.loadAssetsGroup('illustrations.placeholders', {
  emptyCart: require('emptyCart.png'),
  emptyProduct: require('emptyProduct.png'),
});
Assets.loadAssetsGroup('illustrations.emptyStates.', {
  noMessages: require('noMessages.png'),
  noContacts: require('noContacts.png'),
});

然后,在使用Image组件时,通过设置assetGroup,来使用我们自己的AssetsGroup

<Image assetName="emptyCart" assetGroup="illustrations.placeholders"/>

同样,我们也可以使用Image原来的风格,设置Image的source

<Image source={Assets.icons.icon1}/>

丰富的控件

UILib提供了丰富的控件,具体可以查看官方文档

  • Action Bar
  • Action Sheet (cross-platform)
  • Avatar
  • Badge
  • Basic List
  • Button
  • Card
  • Connection Status Bar
  • List Item
  • State Screen
  • Loader Screen
  • Page Control
  • Picker
  • Stepper
  • Text
  • TextInput
  • MaskedInput
  • TagsInput

不过我目前主要使用的是他们的View、Text、Button等基础的几个组件。

注意事项(坑?)

  • Text组件支持margin,但不支持padding

比如这样设置,是无效的

<Text padding-10">...</Text>

我猜想他们这样设计的目的,是认为Text作为文字展示的内容组件(content component),设置padding是不合理的。padding的配置交给容器组件(container component),比如View,可能会更合理。

  • TouchableOpaciply不支持margin、padding等布局属性

这个设定刚开始我不太习惯,一度以为是UILib的bug,后来查了下,他们的TouchableOpaciply就是没有提供这些属性。我猜想wix团队是希望把布局的代码集中在View上。TouchableOpaciply专注于实现点击这个功能。

使用习惯

  • theme

我喜欢在项目中创建一个叫theme.js的文件,里面配置项目中需要用到的颜色和字体

import {Typography, Colors} from 'react-native-ui-lib'

Colors.loadColors({
    primary: '#4C6FB0',
    secondary: '#7DC8FF',

    border: '#bbbbbb',
    line: '#c5c5c5',
    paper: '#f3f3f3',
    highlighted: '#f9f9f9',

    lightGray: '#bbbbbb',
    gray: '#888888',
    darkGray: '#444444',

    green: '#176500',
    red: '#FF0032',
    blue: '#02008E',
    yellow: '#FFB400',
    white: '#FFFFFF',
    black: '#000000',
    transparent: 'transparent',

    defaultText: '#666666',
    lightText: '#aeaeae',
    darkText: '#444444',
})

Typography.loadTypographies({
    h1: {fontSize: 18, fontWeight: 'bold', color: Colors.darkText},
    h2: {fontSize: 16, color: Colors.darkText},
    h3: {fontSize: 15, color: Colors.darkText},
    h4: {fontSize: 14, color: Colors.defaultText},
    h5: {fontSize: 12, color: Colors.lightText},
})

然后在App的入口,导入这个文件

import theme from './App/theme'

这样,App启动的时候,就可以加载我所需要的样式配置。

  • 适量的使用UILib提供的布局属性

正所谓物极必反。UILib虽然提供了便捷的布局方式,但是如果在项目中过量的使用,反而会适得其反。比如下面两种风格的代码

第一种

<View bg-primary paddingLeft-5 paddingTop-8 paddingRight-10 paddingB-20 row centerV>
    <Image
        style={styles.avatar}
        source={require('../../img/mine/avatar.png')}
    />
</View>

第二种

<View style={styles.container}>
    <Image
        style={styles.avatar}
        source={require('../../img/mine/avatar.png')}
    />
</View>

当一个View的布局比较复杂的时候,我推荐使用第二种方式。因为如果一个组件结构比较复杂,如果全部通过第一种方式,那么以后阅读代码的时候,大量的布局代码势必会造成干扰。
如果一个View、Text只需要设置一、两个布局样式,我推荐使用第一种设置方式。如果超过了三种,则推荐使用第二种方式。

更多

如果想要了解更多React Native的实战技巧,欢迎观看本人刚推出的《ReactNative实战-美团》视频教程,本课程的案例来自我的开源项目高仿美团
课程基于React Native 0.52.0,从创建工程讲起,一步一步编写代码,直至完成整个项目。

腾讯课堂

网易课堂

参考资料

react-native-ui-lib官方Github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容