React Native跨平台的带滑动特效的TabBar

React-Native Logo

0x00 当然,我在扯淡

还是这个标题,当然,我在扯淡。一来呼应之前的文章,二来用来批判这么做的不对。

当然,不管是呼应之前的文章,还是来批判,我都是在扯淡……

事实上,iOSandroid各自在UI视觉上有自己的不同表达方式,强行将二者合为其一是不科学的做法,虽然现在各类app大多都是android视觉迁就iOS(主要表现在TabBar上面,Tab bar是iOS当中的核心UI组件,但是android里面官方却不是十分提倡,官方这么提倡自然有他的道理,毕竟android有三个虚拟的物理按键在)。

0x01 然并卵,省事还是有必要的

虽然理论视觉上我们不该这么做,而且react-native官方也只有TabBarIOS,并没有TabBarAndroid。但是市面上还是有不少第三方库可以做到iOSandroid统一使用同一个tabbar的react-native组件。

1
2
3
4
5
React Native的slogan是learn once, run anywhere,显然不是write once, run anywhere。
React Native提供了一套JS解决iOS和android应用开发的方案,但是它并非一个写一种代码能跑在多个平台的方案(当然,使用react native也可以write once, run anywhere,但是在视觉美观度和app性能方面可能会做某些程度的牺牲)。

ReactNative官方给到了类比`TabBarIOS`的`DrawerLayoutAndroid`,这里是地址:
http://www.reactnative.com/react-native-for-android/

回归到Railay项目,我准备使用同一套代码来构建iOS和android双app,主要出发点还是图省事。实际生产当中,情酌情考虑。

0x02 react-native-scrollable-tab-view一个很棒的库

React Native Scrollable Tab View (react-native-scrollable-tab-view)是一个ScrollView组管理组件,他可以协调调度各个ScrollView的滑动、切换,并且它是支持自定义Tab Bar的。

1
2
3
4
5
GitHub:
https://github.com/skv-headless/react-native-scrollable-tab-view

说明:
Tabbed navigation that you can swipe between, each tab can have its own ScrollView and maintain its own scroll position between swipes. Pleasantly animated. Customizable tab bar https://www.npmjs.com/package/react-native-scrollable-tab-view

简单的说,react-native-scrollable-tab-view可以用来构建类似android早期的TabHost,iOS的Tab Bar的应用,并且它有些类似于android的ViewPager,可以在不同的Tab之间滑动切换。

0x03 开始使用这样一个Amazing的组件库

  1. npm 安装组件库
1
npm install react-native-scrollable-tab-view --save
  1. 统一iOS和android入口文件

index.ios.jsindex.android.js中的文件替换成以下内容(两个内容是一样的)

1
2
3
4
5
6
import React from 'react'
import {
AppRegistry
} from 'react-native'
import Root from './App/Root'
AppRegistry.registerComponent('Railay', ()=>Root)

根目录(ios/android目录同级目录)新建文件夹,名曰App,在App文件夹下新建文件Root.js,文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import React, { Component } from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native'

export default class Root extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to Railay!
</Text>
<Text style={styles.instructions}>
This is the line one
</Text>
<Text style={styles.instructions}>
Refresh : CMD + R for iOS / Double R for Android,{'\n'}
Menu: Cmd + D / Menu or shake for dev menu!
</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});

这个时候是时候在android和iOS模拟器上跑一下看看了。理论上是不会有错误的。

  1. 代码中import组件

在文件/App/Root.js当中,引入组件仓库

1
import ScrollableTabView from 'react-native-scrollable-tab-view'

再刷新一下看看,如果没有错误,说明安装组件没有什么问题。可以愉快的玩耍了!

  1. 使用组件

开始玩啥了!我们从最简单的使用开始:

使用以下代码覆盖/App/Root.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React, { Component } from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native'
import ScrollableTabView from 'react-native-scrollable-tab-view' //导入组件

export default class Root extends Component {
render() {
return (
<ScrollableTabView>
<View tabLabel="Share" />
<View tabLabel="Activity" />
<View tabLabel="Post" />
<View tabLabel="Message" />
<View tabLabel="Me" />
</ScrollableTabView>
);
}
}

ScrollableTabView标签是我们导入的组件库的标签,里面放置了5个View,并且这里给5个View分别添加了不同的tabLabel

这里的tabLabel一定要写成不一样的,不然会报错,因为组件查找视图是通过tabLabel来进行的。同时,这里的tabLabel也会展现在Tab上面。效果如下:

android

iOS

这逼装的,简直是有模有样的样子。不过,工作还没完。

  • 为什么Tab在上面?
  • 为什么我们不把这五个View给组件化?

下面,一个一个来。

  1. 自定义Tab
1
-------
  1. 自定义View组件
1
-------