1.Reative Native介绍
Facebook于2015年15日发布React Native,发展成长至今,它为原生手机端App必不可少的开发模式之一。目前比较成熟的跨平台方案:
- React Native, Vue+Weex
- Appcan
- Flutter
React Native已经玩了对多端的支持,实现了真正意义上的面向配置开发;开发人员可以只使用javaSript也能编写原生移动,结合React语法构建组件,实现Adnroid,IOS两端代码的复用,并发布上线
2.React Native搭建环境
https://www.reactnative.cn/docs/getting-started.html
1 | cd 你的工程所在的目录 |
3.ReactNative工程启动流程
3.1 工程启动流程分析
IOS工程和Android工程一启动,就会加载目录中的index.js文件,通过AppRegistry去注册组件,并把注册的组件完成的组件输出给IOS端或Andorid端
3.2 主要文件分析
inedx.js
1
2
3
4
5
6
7
8
9
10
11/**
* @format
*/
// 引入注册组件类并调用注册方法
import {AppRegistry} from 'react-native';
// 引入组件
import App from './views/App';
// 引入输出组件的名称
import {name as appName} from '../app.json';
// 注册组件,程序的主入口
AppRegistry.registerComponent(appName, () => App);App.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/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
// 引入React支持
import React from 'react';
// 引入组件
import {
SafeAreaView,
View,
Text,
StatusBar,
} from 'react-native';
// 渲染组件
const App: () => React$Node = () => {
return (
<>
<StatusBar barStyle="dark-content"/>
<SafeAreaView>
<View>
<Text>Hello React Native</Text>
</View>
</SafeAreaView>
</>
);
};
// 导出组件
export default App;android
andorid目录,react native将js编译打包成原生andorid
ios
ios目录,react native将js编译打包成原生ios
3.3 App.js文件运行步骤
- 加载React模块,使用其内部的API,比如JSX语法
- 加载React Native原生组件,比如:
SafeAreaView
,StyleSheet
,View
- 自定义组件类,作为模板输出
- 创建样式,传入样式对象,根据样式中的对象描述,创建样式表
- 导出当前模块
4 FlexBox布局
4.1 FlexBox是什么意思?
- flexbox(弹性盒子):能够伸缩或者很容易变化,以适应外界条件的变化
- box(盒子):通用的矩形容器
提示:CSS 布局中的flex布局同理
4.2 什么是FlexBox布局?
弹性盒模型(The Flexible Box Module),又叫Flexbox,意为“弹性布局”,旨在通过弹性的方式来对齐和分布容器中内容空间,使其能够适应不同的屏幕,为盒装模型提供最大的灵活性。
Flex布局的主要思想:让容器又能力让妻子组件能够改变其宽度、高度(甚至顺序),以最佳方式填充可用空间。
React native中FlexBox是这个规范的一个子集
4.3 Flexbox在开发中的应用场景
Flexbox在布局宏能够解决什么问题
- 浮动布局
- 各种机型屏幕的适配
- 水平和垂直居中
- 自动分配宽度
- …..
在css中,常规的布局是基于块和内联流方向,而Flex布局时基于flex-flow流,flex-flow能够改变容器的主轴方向:
容器默认存在两根轴:水平主轴(main axis)和垂直的交叉轴(cross axis),主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴开始位置叫cross start。结束位置叫做cross end。项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉空间叫做 cross size。
5. RN常用组件
5.1 View组件
React Nativr组件View,其作用等同于IOS中的UIView,Android中的android.View,或是HTML中
View属性:https://www.reactnative.cn/docs/view
1 | <View style={{ |
5.2 Text组件
一个用于显示文本的ReactNative组件,和Android中的TextView组件或者OC中的UILabel组件类似,专门用来显示基本的文本信息:除了基本你的显示外部之外,可以进行嵌套显示,设置样式,以及可以做事件(例如:点击)处理。
Text属性:https://www.reactnative.cn/docs/text#numberoflines
5.3 Image组件
在开发中还有一个非常重要的组件Image,通过这个组件可以展示各种各样的图片、而且在React Native中该组件可以通过多种方式加载图片资源。包括网络图片、静态资源、临时的本地图片、以及本地磁盘上的图片(如相册等)
Image属性:https://www.reactnative.cn/docs/image
常用使用,三种加载方式
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80import React, {Component} from "react";
import PropTypes from 'prop-types';
import {View, Image, StyleSheet, ImageBackground, ScrollView, Text,Dimensions} from 'react-native'
class LYImage extends Component {
state = {
imageUrl1: 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3593094404,627203995&fm=26&gp=0.jpg',
imageUrl2: 'https://goss.veer.com/creative/vcg/veer/612/veer-167625828.jpg?x-oss-process=image/format,webp',
imageUrl3: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='
};
static propTypes = {};
render() {
const {imageUrl1, imageUrl2, imageUrl3} = this.state;
const { width, height, scale, fontScale } = Dimensions.get('window');
return (
<View>
<ScrollView>
{/*本地加载*/}
<Image
source={require('../assets/image/code.png')}
style={{
width: 200,
height: 200,
}}
borderRadius={100}
overflow={'hidden'}>
</Image>
{/*加载网络图片,通过uri来加载的图片都必须设置宽高否则无法显示图片*/}
<Image
style={style.logo}
source={{
uri: imageUrl1
}}
resizeMode={'contain'}>
</Image>
<Image
style={style.logo}
source={{
uri: imageUrl2
}}
resizeMode={'contain'}>
</Image>
{/*Base64加载*/}
<Image
style={style.logo}
source={{
uri: imageUrl3
}}
resizeMode={'contain'}>
</Image>
{/*图片作为背景*/}
<ImageBackground
style={{
width,
height:100,
marginBottom:20
}}
source={{
uri: imageUrl2
}}
resizeMode={'cover'}>
<Text>
这是ImageBackground实现的背景图
</Text>
</ImageBackground>
</ScrollView>
</View>
)
}
}
const style = StyleSheet.create({
logo: {
width: 100,
height: 200,
}
})
export default LYImage;5.3 综合运用-九宫格
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
46
47
48
49
50
51
52
53
54
55
56
57
58import React, {Component} from "react";
import PropTypes from 'prop-types';
import {View, Dimensions, StyleSheet, Text, Image} from 'react-native'
class LYImageDemo extends Component {
state = {};
static propTypes = {};
render() {
return (
<View style={style.container}>
{this._imageItem()}
</View>
)
}
_imageItem = () => {
// 1.获取常量
let screenW = Dimensions.get('window').width;
let cols = 3, boxW = 100, boxH = 120;
let hMargin = (screenW - boxW * cols) / (cols + 1);
let vMargin = 20;
let dataArr = require('../assets/data/flower');
// 2. 组件数组
let itemArr = [];
// 遍历数组
dataArr.forEach((item, index) => {
itemArr.push(
<View key={index} style={{
backgroundColor: 'red',
width: boxW,
height: boxH,
marginLeft: hMargin,
marginTop: vMargin,
justifyContent: 'center',
alignItems: 'center'
}}>
{/*RN种存放在Android的Drawable目录下的图片可不带后缀直接引用*/}
<Image source={{uri: item.icon}} style={{width: 80, height: 80}}/>
<Text>
{item.name}
</Text>
</View>
);
})
return itemArr;
};
}
const style = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
}
})
export default LYImageDemo;
效果图 :
5.4 TextInput
文本输入框,相当于OC中的UITextFiled,在用法和属性方面,两者都有很大的借鉴之处:通过键盘将文本输入到应用程序的一个基本的组件。
本组件的属性提供了多种特性的配置,譬如自动完成,自动大小写、占位符、以及多种不同的键盘类型(如纯数字键盘)等待
官方文档:https://www.reactnative.cn/docs/textinput
5.5 ScrollView组件
从移动端开发的经验来看,scrollView无疑时开发中最重要的一个组件,比如后面会学到的FlatList就是继承它。那么,在开发中比如:焦点图、引导页等地方都有它的影子。
一个包装了平台的ScrollView(滚动视图)的组件。同时还集成了触摸锁定的“响应者”系统。
5.5.1 两个重点
ScrollView必须有一个确定的高度才能正常工作
它实际上所做的的就是将一系列不确定高度的子组件装进一个确定高度的容器(通过滚动操作).
通常由两种做法:
- 直接给该ScrollView进行设置高度(不建议)
- ScrollView中不要加{flex:1}
ScrollView内部的其他响应者尚无法阻止ScrollView本身成为响应者
5.5.2 ScrollView常用属性
https://www.reactnative.cn/docs/scrollview
6. 网络通讯
本文档贡献者: sunnylqm(100.00%)
很多移动应用都需要从远程地址中获取数据或资源.你可能需要给某个REST API发起POST请求以提交用户数据,又或者可能仅仅需要从某个服务器上获取一些静态内容—-以上就是你会用到东西,新手可以对照这个简短的视频教程加深理解.
发起请求:
要从任意地址获取内容的话,只需要地将网址作为参数传递给fetch方法即可(fetch这个词本身也就是获取的意思);
1 | fetch('https://mywebsite.com/mydata.json') |
Fetch 还有可选的第二个参数,可以用来定制 HTTP 请求一些参数。你可以指定 header 参数,或是指定使用 POST 方法,又或是提交数据等等:
1 | fetch('https://mywebsite.com/endpoint/', { |
提交数据的格式关键取决于 headers 中的Content-Type
。Content-Type
有很多种,对应 body 的格式也有区别。到底应该采用什么样的Content-Type
取决于服务器端,所以请和服务器端的开发人员沟通确定清楚。常用的’Content-Type’除了上面的’application/json’,还有传统的网页表单形式,示例如下:
1 | fetch('https://mywebsite.com/endpoint/', { |
可以参考Fetch 请求文档来查看所有可用的参数。
7. React-Navigation
React-Navigation官方文档:https://reactnavigation.org/docs/getting-started
1.1 项目初始化完成后,集成React Navigation@4.x.x
在项目的根目录下运行命令:
1 | yarn add react-navigation react-native-reanimated react-native-gesture-handler react-native-screens react-navigation-stack react-navigation-tabs |
tip:navagation4.x 要对应stack1.x.x 否则会出现无法解析错误
为了完成react-native-screens在Andorid上的安装,请在andorid/app/build.gradle中dependencies选项中添加如下两行依赖:
1 | implementation 'androidx.appcompat:appcompat:1.0.0-rc01' |
1.2 使用
屏幕切换
1
2
3
4this.props.navigation.navigate('组件路由名字')
this.props.navigation.push('组件路由名字')
this.props.navigation.goBack('组件路由名字')
this.props.navigation.popToTop('组件路由名字')navigate:会判断栈中有没有这个组件,如果有则返回到那个页面,没有则创建一个新的组件压入栈展示,
push:创建一个新的组件,进行压栈展示
goBack:返回上一个页面:
popToTop: 回到首页组件
页面之间传递参数
this.proprs.navigation.navigate 方法可以传递参数到下一个页面,代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<View style={{
justifyContent: 'center',
backgroundColor: 'pink',
flex: 1,
alignItems: 'center'
}}>
<Text>首页</Text>
<Button
onPress={() => this.props.navigation.navigate('Detail', {
newsId: '001',
newsName: '这是一条信息',
newsTag: '重要'
})}
title="跳转详情页"/>
</View>页面接收参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18render() {
const {navigation} = this.props;
return (
<View style={{
justifyContent: 'center',
backgroundColor: 'cyan',
flex: 1,
alignItems: 'center'
}}>
<Text>详情页</Text>
<Text>newsId:{JSON.stringify(navigation.getParam('newsId', 'NO-ID'))}</Text>
<Text>newsName:{JSON.stringify(navigation.getParam('newsName', 'NO-NEWS'))}</Text>
<Text>newsTag:{JSON.stringify(navigation.getParam('newsTag', 'NO-TAG'))}</Text>
<Text>整体获取:{JSON.stringify(navigation.state.params)}</Text>
</View>
)
}
}