一、RN搭建开发环境
1.安装依赖软件:
Node.js 8.3以上
D:\Program Files\nodejs\
Python 2.x以上
D:\Python27\
D:\Python27\Scripts
JDK 1.8
Java_Home=C:\Program Files\Java\jdk1.8.0_65
%Java_Home%\bin
Android SDK
ANDROID_HOME=D:\AndroidStudio\SDK
%ANDROID_HOME%\platform-tools
%ANDROID_HOME%\tools
2.Yarn、React Native的命令行工具
Yarn与npm都是软件管理工具,Yarn速度快很多
npm(该命令是node.js中的命令,用于安装软件)
设置npm镜像:
npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global
Yarn、React Native的命令行工具(react-native-cli)
npm install -g yarn react-native-cli
安装完yarn后同理也要设置镜像源:
yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global4
测试:
react-native --version
yarn -v
3.环境使用
React开发环境:VScode
Node.js 8.3以上
Android环境(编译运行环境):AS
SDK platform:开发版本库
Android SDK Platform 26 (0.56)
Android SDK Platform 23 (0.55.4)
Google Api Intel x86 Atom_64 System Image ; intel HAXM (创建虚拟机使用)
SDK bulid tools:代码编译工具
26.0.3 (0.56)
23.0.1 (0.55.4)
4.创建项目运行到模拟器:
方式一:
1.创建项目
react-native init HelloWorld
react-native init HelloWorld --version 0.44.4
2.进入到项目目录中
cd HelloWorld 目录cmd
3.运行
react-native run-android
方式二:
1.导入新项目
使用其他可用项目即可
2.进入到项目目录中
cd HelloWorld 目录cmd
3.运行
react-native run-android
方式三:
Android Studio打开android项目,编译运行,到模拟器
模拟器配置设置:
摇一摇:启动设置页面 Ctrl+M
HOST:配置服务连接地址: 11.11.11.11:8081
开启node服务:
npm start开启
方式四:
直接使用.apk文件转入模拟器
模拟器配置设置:
摇一摇:启动设置页面 Ctrl+M
HOST:配置服务连接地址: 11.11.11.11:8081
开启node服务:
npm start开启
5.RN常用命令:
react-natice init HelloWorld
react-native init HelloWorld --version 0.44
react-native --version
react-native run-android
react-narive run-ios
npm install -g yarn react-native-cli 安装软件
npm start 开启Node服务
二、RN项目结构:
android 编译运行代码
ios 编译运行代码
node_modules 自动生成三方依赖库
App.js 显示的组件页面
index.js 渲染显示页面
AppRegistry.registerComponent('HelloWorld', () => App);
将APP组件渲染到Android获取IOS中"HelloWorld"标记
Android渲染路径:
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected String getMainComponentName() {
return "HelloWorld";
}
IOS渲染路径:
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"HelloWorld"
initialProperties:nil
launchOptions:launchOptions];
package.js 系统项目配置文件
三、页面组件分析
index.js 渲染显示页面
导入依赖:react-native
import { AppRegistry } from ‘react-native’;
import App from ‘./App’;
渲染:将App组件替换HelloWorld标记
AppRegistry.registerComponent('HelloWorld', () => App);
App.js 显示的组件页面
导入依赖:react(自定义组件类) react-native(使用RN中的控件和API)
import React, { Component } from "react";
import { StyleSheet, Text, View } from "react-native";
定义组件
class App extends Component {
render() {
return (
//渲染页面:RN中控件使用
Welcome to React Native!
To get started, edit App.js
欢迎来到LOL
);
}
}
//创建样式使用
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
}
});
//导出组件
export default App;
四、基本控件以及布局样式
View
View是一个支持Flexbox布局、样式、一些触摸处理、和一些无障碍功能的容器,
并且它可以放到其它的视图里,也可以有任意多个任意类型的子视图
Text
显示文本的React组件,并且它也支持嵌套、样式,以及触摸处理
{this.state.titleText}
Image:
不同类型图片的React组件,包括网络图片、本地资源
同级
下级
上级
同级文件夹
TextInput
输入文本的基础组件。
onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用。
onSubmitEditing的属性,会在文本被提交后(用户按下软键盘上的提交键)调用
this.setState({text})} />
{this.state.text}
Button:
显示一个简单的按钮
是一个简单的跨平台的按钮组件。
Touchable系列组件:
TouchableHighlight来制作按钮或者链接。注意此组件的背景会在用户手指按下时变暗。
在Android 上还可以使用TouchableNativeFeedback,它会在用户手指按下时形成类似墨水涟漪的视觉效果。
TouchableOpacity会在用户手指按下时降低按钮的透明度,而不会改变背景的颜色。
如果你想在处理点击事件的同时不显示任何视觉反馈,则需要使用TouchableWithoutFeedback。
TouchableHighlight
//--------------------------------------------------------------------------------------------------
样式:
style的属性;驼峰命名法,例如将background-color改为backgroundColor
还可以传入一个数组——在数组中位置居后的样式对象比居前的优先级更高,间接实现样式的继承
使用StyleSheet.create来集中定义组件的样式
just red
just bigblue
bigblue, then red
red, then bigblue
const styles = StyleSheet.create({
bigblue: { color: 'blue', fontWeight: 'bold', fontSize: 30, },
red: { color: 'red', },
});
关于样式
(1)普通内联样式:{{}},第一层{}是表达式,第二层{}是js对象;
(2)调用样式表:{样式类.属性}
(3)样式表和内联样式共存:{[]}
(4)多个样式表:{[样式类1, 样式类2]}
弹性布局Flexbox
Flex布局主要思想是:让容器有能力让其子项目能够改变其宽度、高度(甚至是顺序),以最佳方式填充可用空间
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴;默认值是竖直轴(column)方向
在React Native中,有4个容器属性,2个项目属性,分别是:
容器属性:flexDirection flexWrap justifyContent alignItems
项目属性:flex alignSelf
flexDirection容器属性: `row | row-reverse | column | column-reverse`
该属性决定主轴的方向(即项目的排列方向)。
row:主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column(默认值):主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。
flexWrap容器属性: `nowrap | wrap | wrap-reverse`
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
nowrap(默认值):不换行
wrap:换行,第一行在上方
wrap-reverse:换行,第一行在下方。(和wrap相反)
justifyContent容器属性:`flex-start | flex-end | center | space-between | space-around`
定义了伸缩项目在主轴线的对齐方式
flex-start(默认值):伸缩项目向一行的起始位置靠齐。
flex-end:伸缩项目向一行的结束位置靠齐。
center:伸缩项目向一行的中间位置靠齐。
space-between:两端对齐,项目之间的间隔都相等。
space-around:伸缩项目会平均地分布在行里,两端保留一半的空间。
alignItems容器属性:`flex-start | flex-end | center | baseline | stretch`
定义项目在交叉轴上如何对齐,可以把其想像成侧轴(垂直于主轴)的“对齐方式”。
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐 。
center:交叉轴的中点对齐。
baseline:项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
flex项目属性:
“flex-grow”、“flex-shrink”和“flex-basis”三个属性的缩写,
其中第二个和第三个参数(flex-shrink、flex-basis)是可选参数。默认值为“0 1 auto”。
自身相对于父容器的权重占比
alignSelf项目属性:
“auto | flex-start | flex-end | center | baseline | stretch”
align-self属性交叉轴允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。
默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
五、高级使用
ScrollView
可滚动的容器,可放入多个组件和视图,组件并不需要是同类型的。
ScrollView不仅可以垂直滚动,还能水平滚动(通过horizontal属性来设置)
ScrollView必须有一个确定的高度才能正常工作,
实际上所做的就是将一系列不确定高度的子组件装进一个确定高度的容器(通过滚动操作)
ScrollView和ListView/FlatList区别:
ScrollView会简单粗暴地把所有子元素一次性全部渲染出来。
ListView会惰性渲染子元素,只在它们将要出现在屏幕中时开始渲染。
FlatList是0.43版本开始新出的改进版的ListView,性能更优
Scroll me plz
ScrollView>
长列表:FlatList或是SectionList
FlatList组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。
FlatList更适于长列表数据,且元素个数可以增删。
和ScrollView不同的是,FlatList并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。
FlatList组件必须的两个属性是data和renderItem。
data是列表的数据源,而renderItem则从数据源中逐个解析数据,然后返回一个设定好格式的组件来渲染。
列表:
{item.key} }
/>
分组列表
{item} }
renderSectionHeader={({section}) => {section.title} }
/>
使用 Fetch网络请求:
发起请求,设置参数:
fetch(“https://mywebsite.com/mydata.json0?data=1”);
//请求路径
fetch("https://mywebsite.com/endpoint/",
//请求设置
{ //请求方法
method: "POST",
//设置请求头
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
//设置请求体,post;get没有body
body: JSON.stringify({
firstParam: "yourValue",
secondParam: "yourOtherValue"
})
});
获取响应,解析数据:
//请求的网络路径
fetch("https://facebook.github.io/react-native/movies.json")
//通过箭头函数,数据解析,返回解析后的json对象
.then(response => response.json())
//接收解析后的json对象,获取有用数据,在状态机中做数据刷新
.then(responseJson => {
responseJson.movies;
})
//请求错误情况下进行调用
.catch(error => {
console.error(error);
});
箭头函数:
(abc)=>( ) : 返回
简写:
abc =>
(abc)=>{ } : 函数体执行一个 ,无返回值
实例:
constructor(props) {
super(props);
this.state = {
dataValue: []
};
}
componentDidMount() {
fetch("https://facebook.github.io/react-native/movies.json")
.then(response => response.json())
.then(responseJson => {
//刷新数据
this.setState({
dataValue: responseJson.movies
});
})
.catch(error => {
console.log(error);
});
}
render() {
return (
(
{item.title}
)}
/>
);
}
六、集成原生项目
集成到现有原生应用
1.创建RN项目
2.AS中创建原生Android项目
3.将RN中自带的RNActivity,RNApplication页面,导入到Android原生项目中:
1)导入RN依赖
在你的app中 build.gradle 文件中添加 React Native 依赖:
dependencies {
…
implementation “com.facebook.react:react-native:+” // From node_modules.
}
在项目的 build.gradle 文件中为 React Native 添加一个 maven 依赖的入口,必须写在 "allprojects" 代码块中:
allprojects {
repositories {
...
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
...
}
2)在 AndroidManifest.xml 清单文件中声明网络权限:
DevSettingsActivity 界面(即开发者菜单),则还需要在 AndroidManifest.xml 中声明:
3)在AndroidManifest.xml中声明RNActivity,RNApplication
4)通过android项目点击事件,启动RN视图
Intent intent = new Intent(MainActivity.this, RNActivity.class);
startActivity(intent);
4)将android原生项目,导入到RN/android目录:最编译运行
5)运行app项目,启动RN服务即可
七、路由导航:
路由分类:
StackNavigator 跳转页面,传值
TabNavigator 左右切换导航栏
createBottomTabNavigator 底部导航栏(图标)
createSwitchNavigator 身份验证选择
首先是在你的应用中安装此库:
yarn add react-navigation
1)StackNavigator路由表:
配置路由表:
import { StackNavigator } from “react-navigation”;
import Page1 from “./Page1”;
import Details1 from “./Details1”;
const RouteABC = StackNavigator(
{
P: { screen: Page1 },
D: { screen: Details1 }
},
{
initialRouteName: "P"
}
);
跳转页面,传值取值:
//跳转到D对应的页面,传递name,age参数
this.props.navigation.navigate("D", { name: "张三", age: "123" });
//在D页面中取值
{this.props.navigation.getParam("name", "AAA")}
配置标题:
//直接设置标题
static navigationOptions = { title: “Page1” };
static navigationOptions = { header: null };
//获取传递的参数,修改为标题文本
static navigationOptions = ({ navigation }) => ({
title: navigation.getParam("name", "Abc")
});
//更改标题样式
static navigationOptions = ({ navigation }) => ({
title: navigation.getParam("name", "Abc"),
headerStyle: {
backgroundColor: "#f4511e"
},
headerTintColor: "#fff",
headerTitleStyle: {
fontWeight: "bold"
}
});
//跨页面共享通用的navigationOptions
const AppNvg = StackNavigator(
{
Main: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
My: { screen: MyScreen }
},
{
initialRouteName: "Main",
navigationOptions: {
headerStyle: {
backgroundColor: "#f4511e"
},
headerTintColor: "#fff",
headerTitleStyle: {
fontWeight: "bold"
}
}
}
);
2)Tab导航栏:(自带路由功能)
import { TabNavigator } from “react-navigation”;
import JHSreeen from “./JHSreeen”;
import FXSreeen from “./FXSreeen”;
const TieScreen = TabNavigator(
{
JH: {
screen: JHSreeen,
navigationOptions: {
title: “精华”
}
},
FX: {
screen: FXSreeen,
navigationOptions: {
title: “分享”
}
}
},
{
//设置标题栏通配效果
navigationOptions: {
title: “标题”
},
tabBarPosition: “top”, //Tab摆放位置
//谁设置文本选中前后效果颜色
tabBarOptions: {
activeTintColor: “white”, //激活样式
inactiveTintColor: “gray” //未激活样式
},
swipeEnabled: true, //是否可以滑动
animationEnabled: true //滑动效果
}
);
3)底部导航栏:
使用三方图库:
/**
import { createBottomTabNavigator } from “react-navigation”;
import Ionicons from “react-native-vector-icons/Ionicons”;
const Home = createBottomTabNavigator(
{
Topic: {
screen: Topic,
navigationOptions: {
title: “帖子”
}
},
Publish: {
screen: Publish,
navigationOptions: {
title: “发布”
}
},
My: {
screen: My,
navigationOptions: {
title: “我的”
}
}
},
{
//谁设置文本选中前后效果颜色
tabBarOptions: {
activeTintColor: “#FF0000”, //激活文本图片样式
inactiveTintColor: “#0000FF”, //未激活文本图片样式
activeBackgroundColor: "#2296F3", //激活背景样式
inactiveBackgroundColor: "#ffffff" //未激活背景样式
},
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === "Topic") {
//切换不同的图标
//iconName = `ios-document${focused ? "" : "-outline"}`;
//iconName = `${focused ? "ios-document" : "ios-document-outline"}`;
iconName = "ios-document";
} else if (routeName === "Publish") {
iconName = "ios-create";
} else if (routeName === "My") {
iconName = "ios-person";
}
return ;
}
})
}
);
4)身份验证路由:
Route.js 身份验证的路由页面,主要用于配置认证页面
import { createSwitchNavigator } from “react-navigation”;
import HomeScreen from “./HomeScreen”;
import SignInScreen from “./SignInScreen”;
import AuthLoadingScreen from “./AuthLoadingScreen”;
const Route = createSwitchNavigator({
AuthLoading: { screen: AuthLoadingScreen },
Home: { screen: HomeScreen },
SignIn: { screen: SignInScreen }
});
AuthLoadingScreen.js 判断登录状态,跳转不同页面
//判断SP文件中是否保存了userToken字段:true 登录状态 false:未登录状态(读SP文件状态)
_bootstrapAsync = async () => {
//获取登录状态
const userToken = await AsyncStorage.getItem(“userToken”);
//根据状态判断:跳转不同页面
this.props.navigation.navigate(userToken ? “Home” : “SignIn”);
};
SignInScreen.js 进入登录页面,说明未登录,要求用户登录(将登录信息保存到SP文件)
HomeScreen.js 进入主页面,说明已经登录成功了,用户有可能注销登录(将SP文件中的登录信息清空)
八、动画使用
constructor(props) {
super(props);
this.state = {
// 1. 初始化动画值
scale: new Animated.Value(0)
};
}
render() {
return (
// 2. 将动画值绑定到style的属性:opacity透明度
// opacity: this.state.fadeAnim,
transform: [{ scale: this.state.scale }]
}}
>
RN的动画使用
);
}
press = () => {
//3.动画处理以及开启
Animated.timing(this.state.scale, {
toValue: 3,
duration: 5000
}).start();
};
press = () => {
//3.动画处理以及开启
const animations = [
Animated.timing(this.state.opacity, {
toValue: 3,
duration: 5000
}),
Animated.timing(this.state.width, {
toValue: 500
}),
Animated.timing(this.state.height, {
toValue: 500
})
];
Animated.stagger(5000, animations).start();
};
九、常用控件以及常用Api
详情见RN中文官网
十、项目开发
分析用到的知识点
搭建框架(分析如何搭建,搭建思路)
创建项目,编译运行(初始版本)
编写模块代码。。。。。。
提交代码管理工具,做备份