学习React Native 这大半年以来,说一句心里话,是非常适合Android开发者上手iOS开发的,可以不用OC直接开发iOS App还是非常有吸引力的,可以用非常短的时间开发出一个App。而且JavaScript的话和Java语言挺像的,现在ES6标准中,我觉得写JavaScript代码已经和Java非常像了,比如class关键字,当然ES6标准下的JavaScript特性还有很多很多,我本人也在不断的学。总来的说,对Android开发者来说,开始React Native开发是非常值得学习,而且是快速开发iOS的一条途径吧

创建一个React Native工程

因为RN开发是使用JavaScript的开发的,以前是用npm来管理JS的依赖,现在官方推荐使用yarn,所以创建工程之前最好安装一下yarn。官网推荐使用命令行工具:create-react-native-app这里是创建工程的官方文档,我就不多说了

创建一个工程以后进入工程目录你发现有这么几个文件:

  • android
  • ios
  • node_modules
  • app.json
  • index.js
  • package.json
  • App.js
  • yarn.lock

很好,你已经创建成功了,现在你可以运行react-native run-ios 启动一个iOS模拟器来运行RN代码了,怎么样,是不是很简单?

需要说明一下,运行RN(也就是你运行上面这句命令行)的时候你开发使用的电脑会启动一个node server,因为如果开发一个App话会需要很多的js文件,这个server的作用就是帮我们将这些js文件打包成一个bundle文件,开发过程中的App可以实时的获取最新的代码,可以用这个url:http://localhost:8081/index.js来查看生成的js bundle代码

React Native中的各种组件和容器

我就举几个和Android中对应的组件,其实RN中的一些组件和Android中命名还是挺像的

  • Text 对应TextView
  • Image 对应ImageView
  • Input 对应EditText
  • Button 对应Button
  • FlatList 对应ListView或RecyclerView
  • ScrollView 对应ScrollView

因为习惯了Android中的各种ViewGroup的便捷,我刚开始学习RN的时候很有一个疑问,RN中有没有类似的容器呢?

答案很简单,没有。

因为RN是用JavaScript来开发的,本质上还是用了React框架,而React是使用Flex来布局页面的。简单讲Flex部分支持水平或垂直布局Child,和LinearLayout 比较类似。下面代码中flex: 1 表示这个View充满整个父容器,具体Flex布局可以看这里

1
2
3
<View style={{flex: 1}}>
</View>

Flex布局最大的一个特点就是Child是按顺序排列的,不能重叠,那么如果说一个View需要固定的显示在屏幕上的某个位置该怎么办呢?

答案就是,绝对布局

1
2
3
4
5
6
miniSections: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
}

说起绝对布局,Android中是被废弃掉的一种布局方式,因为这种方式不能适配碎片化的屏幕。但是在RN中只能使用这种布局方式来实现某个特殊的布局,比如某个View需要固定显示在屏幕上

那么要适配多屏幕怎么办呢?我的方法也很土。。。就是根据设计图的尺寸,App在显示的时候,动态的计算比如View的高度,间距什么的

React Native页面跳转

这是另一个让我在开始学RN时产生的困惑,因为开发Android产生的思维惯性,我本能的想到是不是有什么startComponent(...props) 这样类似的函数让我调用去打开一个新的页面。可惜没有。。。

重新思考一下Android启动一个Activity的时候,AMS会自动用栈帮我们记录这个App所有已经打开的页面,方便我们返回的时候正确的显示之前的页面

RN中也需要这样的机制,RN框架提供了这么一个组件,叫Navigator,下面看一下这个组件使用:

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
<Navigator
style={styles.container}
itemWrapperStyle={styles.allPages}
initialRoute={{
name: 'Login',
index: 0,
component: LoginPage,
}}
renderScene={(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}}
onForward={() => {
let nextIndex = route.index + 1;
navigator.push({
name: 'Scene ' + nextIndex,
index: nextIndex,
});
}}
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FloatFromBottom;
}}
onBack={() => {
if (route.index > 0) {
navigator.pop();
}
}}
/>

这个Navigator用起来比较麻烦,npmjs上有很多大神已经写出了很多优秀的RN路由框架了,React Navigation 就是其中一个非常优秀,而且我觉得非常好用的框架,网上有非常详细的文档,我就不细说了

React Native数据传递

在RN中功能都可以被拆分为大大小小的组件,比如class UserView extends Component,使用这个UserView的组件可以传入一个user object,可以用下面的代码

1
2
<UserView
user={user}/>

这就是表示将一个user 对象(大括号中的),通过user字段传入UserView这个组件,然后我们可以在UserView中可以通过this.props.user 来获取这个值