一、创建ReactNative项目
1.1、指令创建
React Native 有一个内置的命令行界面,你可以用它来生成一个新项目。您可以使用 Node.js 附带的 访问它,而无需全局安装任何内容。让我们创建一个名为“AwesomeProject”的新 React Native 项目
npx react-native@latest init AwesomeProject
现在ReactNative的项目就创建完成了,我们就用VScode打开,运行项目以及编辑。
一级标题
├── /test # RN生成,测试目录
├── /android # RN生成,android代码目录,具体见下图
├── /ios # RN生成,代码目录,具体见下图
├── /node_modules # 自动生成,安装依赖的目录,不会被提交
├── .babelrc # RN生成,Babel配置文件
├── .buckconfig # RN生成,Buck是Mac OS X和Linux使用的构建工具,Buck的配置文件,buck是Facebook开源的高效构建系统
├── .flowconfig # RN生成,Flow是一个静态的类型检查工具
├── .gitattributes # RN生成,配置Git对一个特定的子目录或子文件集运用那些设置项
├── .gitignore # RN生成,配置Git忽略提交的文件
├── .watchmanconfig # RN生成,Watchman用于监控文件变化,辅助实现工程修改所见即所得
├── yarn.lock # RN生成,Yarn是node包管理器,yarn.lock文件使程序在不同的机器上以同样的方式安装依赖
├── package.json # RN生成,用于描述项目的基本信息以及需要的依赖信息
├── index.android.js # RN生成,android入口文件
├── index.ios.js # RN生成,ios入口文件
├── index.web.js # 自定义,web入口文件
├── CHANGELOG.md # 自定义,版本更新日志
├── README.md # 自定义,项目运行说明
2.1、运行项目
第 1 步:启动项目
npx react-native start
第 2 步:启动应用程序
npx react-native run-android
第3步:项目启动完成
第4步、设置模拟器悬浮在窗口最顶端段
三 React Native核心组件
四 基本语法
4.1 StyleSheet
StyleSheet是RN声明样式的API
RN中的样式与CSS的不同
- 没有继承性:RN中的继承只发生在Text组件上
- 样式名采用小驼峰命名:fontSize VS font-size
- 所有尺寸都是没有单位:width:100
- 有些特殊的样式名:marginHorizontal(水平外边距),marginVertical(垂直外边距)
RN样式的声明
- 通过style属性直接声明
属性值为对象:<组件 style={{样式}}/>; 属性值为数组:<组件 style={[{样式1},...{样式2}]}/>
- 在style属性中调用StyleSheet声明样式
引入:import {StySheet,View} from 'react-native'
声明:const styles=StyleSheet.create({foo;{样式1},bar:{样式2}})
使用:<View style={[styles.foo,styles]}>内容</View>
创建组件,RNC快捷命令
/* eslint-disable react-native/no-inline-styles */
import React, {Component} from 'react';
import {StyleSheet, Text, View} from 'react-native';
export default class App extends Component {
render() {
return (
<View>
{/* 通过style属性直接声明 */}
<Text style={{fontSize: 30, color: 'blue'}}> textInComponent </Text>
<Text style={[{color: 'red'}, {color: 'yellow'}, {fontSize: 30}]}>
textInComponent
</Text>
{/* 在style属性中调用StyleSheet声明样式 */}
<Text style={[styles.foo]}>Hello World</Text>
<Text style={[styles.bar]}>Hello World</Text>
</View>
);
}
}
// 声明样式对象
const styles = StyleSheet.create({
foo: {
fontSize: 40,
fontWeight: 'bold',
},
bar: {
fontSize: 30,
fontWeight: 'bold',
},
});
按Ctrl+M,弹出调试菜单,点击热更新,页面就会更
热更新效果
4.2、Flexbox布局
Flexbox(弹性布局)——术语
- 容器(container):采用Flex布局的元素,称为Flex容器(Flex container),简称“容器”。
- 项目(Item):容器所有的子元素,称为Flex项目(Flex item),简称“项目”。
- 主轴:(main axis)
- 交叉轴:(cross axis)
Flexbox ——属性(常用)
flexDirection:声明主轴方向:row(Web默认)| column(RN默认)
justifyContent:声明项目的主轴的对齐方式
alignItems:声明项目在交叉轴的对齐方式
flex:声明项目在主轴上的尺寸比例
弹性布局各属性介绍(https://blog.csdn.net/qq_39431405/article/details/144110042)
4.2.1、flexDirection
FlexDirection.tsx
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {Text, StyleSheet, View,ScrollView} from 'react-native';
export default class FlexDirection extends Component {
render() {
return (
// View非滚动
<View>
<Text style={[styles.div1]}> 主轴方向 </Text>
{/* ScrollView可滚动 */}
<ScrollView>
<Text style={[styles.div2]}>flexDirection:"colum(默认)" </Text>
<View style={[styles.container]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"colum-reverse" </Text>
<View style={[styles.container,styles.flexColumnReverse]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"row" </Text>
<View style={[styles.container,styles.flexRow]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"row-reverse" </Text>
<View style={[styles.container,styles.flexRowReverse]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
height:150,
margin:10,
borderWidth:1,
borderColor:'pink',
},
div1:{
fontSize:30,
marginHorizontal:10,
},
div2:{
fontSize:24,
marginHorizontal:10,
},
itemBase:{
height:30,
borderWidth:1,
borderColor:'red',
backgroundColor:'pink',
padding:5,
textAlign:'center',
},
flexColumn:{
flexDirection:'column',
},
flexColumnReverse:{
flexDirection:'column-reverse',
},
flexRow:{
flexDirection:'row',
},
flexRowReverse:{
flexDirection:'row-reverse',
},
});
运行效果:
4.2.2、justifyContent
JustifyContent.tsx
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {Text, StyleSheet, View,ScrollView} from 'react-native';
export default class JustifyContent extends Component {
render() {
return (
// View非滚动
<View>
<Text style={[styles.div1]}> 项目在主轴上对齐方式 </Text>
{/* ScrollView可滚动 */}
<ScrollView>
<Text style={[styles.div2]}>JustifyContent:"flex-start(默认)" </Text>
<View style={[styles.container,styles.flexRow,styles.JustifyContentStart]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"flex-center" </Text>
<View style={[styles.container,styles.flexRow,styles.JustifyContentCenter]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"flex-end" </Text>
<View style={[styles.container,styles.flexRow,styles.JustifyContentEnd]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"space-around" </Text>
<View style={[styles.container,styles.flexRow,styles.JustifyContentAround]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"space-evenly" </Text>
<View style={[styles.container,styles.flexRow,styles.JustifyContentEvenly]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexDirection:"space-between" </Text>
<View style={[styles.container,styles.flexRow,styles.JustifyContentBetween]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
height:150,
margin:10,
borderWidth:1,
borderColor:'pink',
},
div1:{
fontSize:30,
marginHorizontal:10,
},
div2:{
fontSize:24,
marginHorizontal:10,
},
itemBase:{
height:30,
borderWidth:1,
borderColor:'red',
backgroundColor:'pink',
padding:5,
textAlign:'center',
},
flexRow:{
flexDirection:'row',
},
flexRowReverse:{
flexDirection:'row-reverse',
},
JustifyContentStart:{
justifyContent:'flex-start',
},
JustifyContentCenter:{
justifyContent:'center',
},
JustifyContentEnd:{
justifyContent:'flex-end',
},
JustifyContentAround:{
justifyContent:'space-around',
},
JustifyContentEvenly:{
justifyContent:'space-evenly',
},
JustifyContentBetween:{
justifyContent:'space-between',
},
});
运行效果:
4.2.2、alignItems
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {Text, StyleSheet, View,ScrollView} from 'react-native';
export default class AlignItems extends Component {
render() {
return (
// View非滚动
<View style={{height:'100%'}}>
<Text style={[styles.div1]}> 项目在主轴上对齐方式 </Text>
{/* ScrollView可滚动 */}
<ScrollView>
<Text style={[styles.div2]}>alignItems:"flex-start(默认)" </Text>
<View style={[styles.container,styles.flexRow,styles.alignItemsStart]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>alignItems:"center" </Text>
<View style={[styles.container,styles.flexRow,styles.alignItemsCenter]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>alignItems:"flex-end" </Text>
<View style={[styles.container,styles.flexRow,styles.alignItemsEnd]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>alignItems:"stretch" </Text>
<View style={[styles.container,styles.flexRow,styles.alignItemsStretch]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
<Text style={[styles.div2]}>alignItems:"baseline" </Text>
<View style={[styles.container,styles.flexRow,styles.alignItemsBaseline]}>
<Text style={[styles.itemBase]}>苹果</Text>
<Text style={[styles.itemBase]}>香蕉</Text>
<Text style={[styles.itemBase]}>芒果</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
height:150,
margin:10,
borderWidth:1,
borderColor:'pink',
},
div1:{
fontSize:30,
marginHorizontal:10,
},
div2:{
fontSize:24,
marginHorizontal:10,
},
itemBase:{
height:30,
borderWidth:1,
borderColor:'red',
backgroundColor:'pink',
padding:5,
textAlign:'center',
},
flexColumn:{
flexDirection:'column',
},
flexColumnReverse:{
flexDirection:'column-reverse',
},
flexRow:{
flexDirection:'row',
},
flexRowReverse:{
flexDirection:'row-reverse',
},
alignItemsStart:{
alignItems:'flex-start',
},
alignItemsCenter:{
alignItems:'center',
},
alignItemsEnd:{
alignItems:'flex-end',
},
alignItemsStretch:{
alignItems:'stretch',
},
alignItemsBaseline:{
alignItems:'baseline',
},
});
运行效果:
4.2.3 Flex
Flex.tsx
/* eslint-disable prettier/prettier */
/* eslint-disable react-native/no-inline-styles */
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {Text, StyleSheet, View,ScrollView} from 'react-native';
export default class Flex extends Component {
render() {
return (
// View非滚动
<View style={{height:'100%'}}>
<Text style={[styles.div1]}> 项目在主轴上占比 </Text>
{/* ScrollView可滚动 */}
<ScrollView>
<Text style={[styles.div2]}>flexRow 1:1:1</Text>
<View style={[styles.container,styles.flexRow]}>
<Text style={[styles.itemBase,{flex:1}]}>苹果</Text>
<Text style={[styles.itemBase,{flex:1}]}>香蕉</Text>
<Text style={[styles.itemBase,{flex:1}]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexRow 1:2:3 </Text>
<View style={[styles.container,styles.flexRow]}>
<Text style={[styles.itemBase,{flex:1}]}>苹果</Text>
<Text style={[styles.itemBase,{flex:2}]}>香蕉</Text>
<Text style={[styles.itemBase,{flex:3}]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexColumn:1:1:1 </Text>
<View style={[styles.container,styles.flexColumn]}>
<Text style={[styles.itemBase,{flex:1}]}>苹果</Text>
<Text style={[styles.itemBase,{flex:1}]}>香蕉</Text>
<Text style={[styles.itemBase,{flex:1}]}>芒果</Text>
</View>
<Text style={[styles.div2]}>flexColumn:1:2:3 </Text>
<View style={[styles.container,styles.flexColumn]}>
<Text style={[styles.itemBase,{flex:1}]}>苹果</Text>
<Text style={[styles.itemBase,{flex:2}]}>香蕉</Text>
<Text style={[styles.itemBase,{flex:3}]}>芒果</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
height:150,
margin:10,
borderWidth:1,
borderColor:'pink',
},
div1:{
fontSize:30,
marginHorizontal:10,
},
div2:{
fontSize:24,
marginHorizontal:10,
},
itemBase:{
height:30,
borderWidth:1,
borderColor:'red',
backgroundColor:'pink',
padding:5,
textAlign:'center',
},
flexColumn:{
flexDirection:'column',
},
flexColumnReverse:{
flexDirection:'column-reverse',
},
flexRow:{
flexDirection:'row',
},
flexRowReverse:{
flexDirection:'row-reverse',
},
});
运行效果:
五 响应式布局
5.1 Flexbox模型
React Native 在布局和样式上极大程度上借鉴了 Web 前端所使用的 CSS 规格。CSS 布局方面的算法主要由三个部分组成,首先是解决单个 UI 元素的尺寸问题的 Box 模型(具体由 width,height,padding,border,margin 属性构成),其次是解决 UI 元素相对位置的 Position 模型(具体由 position,top,right,bottom,left 属性构成),最后是解决剩余空间分配问题的 Flexbox 模型。
5.2 Dimensions (获取屏幕信息)
Dimensions API 是 React Native 提供的获取屏幕信息用的 API。开发人员可以通过调用 Dimensions.get()方法取得一个包含屏幕长宽信息的对象,来把握当前用户的设备的屏幕大小,并且以此来简易推测用户是否处于横屏状态。用户使用应用的过程中,由于设备的旋转方向变化或者多应用分屏等情况,屏幕信息可能随时会产生变化。作为可以对应各种变化情况的最佳实践,推荐在组件的 onLayout 的回调中使用 Dimensions.get()方法来获取屏幕信息。
import {Dimensions} from 'react-native';
const windowWidth=Dimension.get('window').width;
const windowHeight=Dimension.get('window').height;
使用Dimensions
创建:DimensionsTest.tsx
/* eslint-disable prettier/prettier */
import React, {Component} from 'react';
import {Text, StyleSheet, View, Dimensions} from 'react-native';
export default class DimensionsTest extends Component {
render() {
return (
<View style={[styles.container]}>
<View style={styles.itemBase}>
<Text style={styles.h3}> 首页 </Text>
</View>
<View style={styles.itemBase}>
<Text style={styles.h3}> 分类 </Text>
</View>
<View style={styles.itemBase}>
<Text style={styles.h3}> 动态 </Text>
</View>
<View style={styles.itemBase}>
<Text style={styles.h3}> 筛选 </Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flexDirection:'row',
},
itemBase:{
justifyContent:'center',
alignItems:'center',
backgroundColor:'pink',
//获取窗口的宽度然后分4份
width:Dimensions.get('window').width / 4,
height:90,
borderWidth:1,
borderColor:'yellow',
//设置字体无效,因为RN不存在继承,需要单独设置
fontSize:25,
},
h3:{
fontSize:24,
},
});
运行效果: