样式---------------
RN中的继承只发生在Text组件中,其他组件样式不能继承
命名采用小驼峰式
所有的尺寸都是没有单位 width:100
特殊的样式命名marginHorizontal(水平外边距),marginVertical(垂直外边距)
RN样式的声明
方式一:通过style属性直接声明
1.属性值为对象 <组件 style={{样式}}>
2.属性值为数据 <组件 style={[{样式1},{样式2}]}> 如果两个样式一样,则后面会覆盖前面
方式二:StyleSheet声明
引入 import {StyleSheet, View} from 'react-native'
声明 const styles = StyleSheet.create({foo:{样式1}, bar:{样式2})
使用 <View stype={[styles.foo, styles.bar]}>内容</View>
弹性布局---------
容器:采用Flex布局的元素称为Flex容器
项目(Item):容器内所有子元素称为Flex项目
主轴(main axis):水平方向
交叉轴(cross axis):垂直方向
获取平台是ios还是android
import {Platform} from 'react-native'
if (Platform.OS === 'android') {} else if (Platform.OS === 'ios') {}
属性
flexDirection声明主轴方向,web默认是row | rn默认是column
justifyContent声明项目在主轴上的对齐方式
alignItems声明交叉轴上的对其方式
flex声明项目在主轴上的尺寸比例
flexWrap: 'wrap'允许换行
响应式布局FlexBox---------
FlexBox
Dimensions
import { Dimensions } from 'react-native'
const windowWidth = Dimensions.get('window').width 获取屏幕宽度
const windowHeight = Dimensions.get('window').height 获取屏幕高度
RN中的核心组件,是对原生组件的封装
原生组件:Android或ios组件
核心组件:RN中常用的,来自react-native的组件
核心组件
View视图组件
安装 yarn add react-native-webview
配置 https://github.com/react-native-webview/react-native-webview
Text文本组件
Alert警告组件
Button按钮组件
Switch开关组件
StatusBar状态栏组件
ActivityIndicator加载指示器组件
Image图片组件
1.加载本地图片
2.加载url地址
3.加载Base64字符串
TextInput输入框组件
Touchable触碰组件
ScrollView滚动视图组件
SectionList分组列表组件
FlatList高性能列表组件
Animated动画组件
创建初始值Animated.Value()单个值、Animated.ValueXY()向量值
将初始值绑定到某个样式属性下
通过动画类型API一帧一帧的更改初始值Animated.decay()加速效果、Animated.spring()弹跳效果、Animated.timing()时间渐变效果
三方组件
WebView相当于内置浏览器
yarn add react-native-webview
Picker下拉框
yarn add @react-native-picker/picker
Swiper展示轮播效果
官网链接
https://github.com/leecade/react-native-swiper
yarn add react-native-swiper
AsyncStorage持久化全局存储系统
配置
https://github.com/react-native-async-storage/async-storage
官网链接
https://react-native-async-storage.github.io/async-storage/docs/install/
安装
yarn add @react-native-async-storage/async-storage
使用
增set(k,v) 删delete(k) | clear() 改update(k,v) 查get(k)
Geolocation获取定位信息
官网地址
https://github.com/react-native-geolocation/react-native-geolocation
添加获取定位信息的授权许可
安装
yarn add @react-native-community/geolocation
配置权限
根据官网配置定位权限
Image-picker点击头像去相册选择还是拍照
安装 yarn add react-native-image-picker
官网链接 https://github.com/react-native-image-picker/react-native-image-picker
使用场景 1.调用摄像头;2.访问相册
react-native-linear-gradient线性渐变组件
安装
yarn add react-native-linear-gradient
配置
https://github.com/react-native-linear-gradient/react-native-linear-gradient
使用
import LinearGradient from 'react-native-gradient'
<LinearGradient start={{x:0, y:0}} end={{x:1,y:0}} colors={['#ddd', '#333']}></LinearGradient>
Redux
安装 yarn add redux react-redux redux-thunk 支持异步操作
创建 store
将store挂载到App组件上
在组件内部使用redux数据
路由鉴权
用户登录
已登录跳到首页
未登录跳到登录页
项目优化
使用第三方组件库 链接:github.com/callstack/react-native-paper
react-native-paper
添加项目logo
修改项目名称 android/app/src/main/res/values/strings.xml
ios/项目名称/Info.plist文件,定位到CFBundleDisplayName
Camera调用摄像头
一、react-native-vision-camera简介:是一个用于构建 React Native 应用程序中与相机相关的功能的库。它提供了一种以高性能和可定制化的方式访问设备相机并捕获图像或视频的方法。该库是基于 iOS 和 Android 的本地相机 API 构建的,并为两个平台提供了统一的 API。它提供了各种功能,如实时图像处理、手动相机控制和自定义取景器叠加层
官方链接 https://react-native-camera.github.io/react-native-camera/docs/installation
安装 yarn add react-native-vision-camera
要使用相机或麦克风,先指定应用需要相机和麦克风权限
苹果需要Info.plist文件<dict>标签中添加以下代码打开相机和麦克风权限,Info.plist在~/ios/ios项目名称/Info.plist目录
<!--相机权限-->
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Camera.</string>
<!--麦克风权限-->
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Microphone.</string>
安卓需要在AndroidManifest.xml文件<manifest>标签中添加以下代码
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
示例
import { useCameraDevices, Camera } from 'react-native-vision-camera'
import * as React from 'react'
import { useRef } from 'react'
export function CameraDemo(props) {
const camara = useRef(null)
// 获取可用镜头
const devices = useCameraDevices()
// 使用前置摄像头
const device = devices.front
return device != null && (
<Camera
ref={camara} //绑定ref
device={device} //绑定设备
isActive={true}
photo={true} //打开相机功能
frameProcessorFps={'auto'}
/>
)
}
二、Frame Processors帧处理器简介:是指对相机捕获的帧进行实时处理的功能模块。在 React Native Vision Camera中,可以使用 Frame Processors 来对相机捕获的帧进行自定义的处理。如:使用帧处理器将视频的每一帧中的人脸来进行检测。
安装
帧处理器模块 yarn add react-native-reanimated
人脸检测模块 yarn add vision-camera-face-detector
三、sion-camera-face-detector简介:是React Native Vision Camera 库提供的一个人脸检测功能模块。它使用了 iOS 和 Android 平台的本地人脸检测算法,并提供了一个简单的 API,使开发人员可以轻松地在他们的应用程序中添加人脸检测功能。
说明 vision-camera-face-detector 提供了一个名为 useFaceDetector 的钩子,可以用于启用人脸检测功能。当使用 useFaceDetector 钩子启用人脸检测时,每次相机捕获到一帧画面时,该功能模块会自动检测画面中的人脸,并返回一个包含人脸信息的数组
示例
import * as React from 'react'
import { runOnJS } from 'react-native-reanimated'
import { Platform } from 'react-native'
import { useCameraDevices, useFrameProcessor, Camera } from 'react-native-vision-camera'
import { scanFaces, Face } from 'vision-camera-face-detector'
import { useRef } from 'react'
export function FaceDetectorDemo(props) {
const [hasPermission, setHasPermission] = React.useState(false)
//存储人脸信息
const [faces, setFaces] = React.useState([])
//提示人脸的消息
const [msg, setMsg] = React.useState(null)
//用于打开相机等
const [isActiveVal, setIsActiveVal] = React.useState(true)
const camara = useRef(null)
//获取可用相机列表
const devices = useCameraDevices()
//使用前置摄像头
const device = devices.front
React.useEffect(() => {
let facesArr = []
facesArr = faces
// faces为帧处理器获得到的人脸图片,从而进行人脸检测处理
if (facesArr.length > 0) {
let face = facesArr[0]
if (JSON.stringify(face.contours) == '{}') {
setMsg('人脸信息不全')
} else {
if (face.leftEyeOpenProbability == 1 && face.rightEyeOpenProbability == 1 && face.pitchAngle == 0 && face.rollAngle == 0) {
setMsg('面部遮挡')
} else {
if (face.leftEyeOpenProbability < 0.8 && face.rightEyeOpenProbability < 0.8) {
setMsg('请睁眼')
} else {
if (!(Math.abs(face.pitchAngle) < 6 && Math.abs(face.rollAngle) < 6 && Math.abs(face.yawAngle) <= 6)) {
setMsg('请正面朝向屏幕')
} else {
//关闭相机
setIsActiveVal(false)
//拍摄照片
takePicture().then(res => {
console.log('成功', res)
}).catch()
}
}
}
}
}
}, [faces])
React.useEffect(() => {
(async () => {
const status = await Camera.requestCameraPermission()
setHasPermission(status === 'authorized')
})()
}, [])
const frameProcessor = useFrameProcessor((frame) => {
'worklet'
const scannedFaces = scanFaces(frame)
runOnJS(setFaces)(scannedFaces)
}, [])
// 拍摄人脸照片
const takePicture = async () => {
if (camara.current) {
let photo = null
// 检测是ios还是安卓平台
if (Platform.OS === 'ios') {
photo = await camara.current.takePhoto({
qualityPrioritization: 'speed',
flash: 'off',
enableAutoRedEyeReduction: true,
})
} else {
photo = await camara.current.takeSnapshot({
quality: 80,
skipMetadata: true,
})
}
// photo.path 为拍摄的人脸照片地址,可以把照片传入后端进行人脸比对
let path = photo.path
}
}
return device != null && hasPermission ? (
<Camera
ref={camara}
device={device}
isActive={isActiveVal}
photo={true}
frameProcessor={frameProcessor}
frameProcessorFps={'auto'}
/>
) : null
}
路由与导航基础
RN中路由是通过React-Navigation来完成的,React中路由是通过React-Router来完成的
官网链接:https://reactnavigation.org
安装
yarn add @react-navigation/native
yarn add react-native-screens react-native-safe-area-context
添加头部文件(放到index.js或App.js文件的顶部)
import 'react-native-gesture-handler'
添加导航容器
引用 import { NavigationContainer } from '@react-navigation/native'
在入口文件中把整个应用包裹在导航容器中<NavigationContainer><Index /></NavigationContainer>
Stack导航
简介
RN中默认没有类似浏览器的history对象
在RN中跳转之前,先将路由声明在Stack中
安装
yarn add @react-navigation/stack
yarn add react-native-gesture-handler
yarn add @react-native-masked-view/masked-view
使用
import { createStackNavigator } from '@react-navigation/stack'
const stack = createStackNavigator()
<Stack.Navigator initialRouteName='Home'><Stack.Screen /></Stack.Navigator>
Navigator属性作用于所有screen
initialRouteName指定默认初始化加载的路由
headerMode声明头部信息(float IOS头部效果,screen Android头部效果,none不显示头部)
screenOptions声明screen属性
Screen属性作用于当前screen,Screen只有一个大的options属性,options中可以声明多个属性
title声明screen标题
headerTitleStyle声明标题样式
headerStyle声明头样式
headerLeft声明左侧内容
headerRight声明右侧内容
headerTintColor标题颜色
BottomTab导航(底部导航)
安装
yarn add @react-navigation/bottom-tabs
使用
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
const Tab = createBottomTabNavigator()
矢量库图标
安装
npm install --svae react-native-vector-icons
官网链接
https://github.com/oblador/react-native-vector-icons
Drawer导航(抽屉导航)
安装
npm install @react-navigation/drawer
使用
import { createDrawerNavigator } from '@react-navigation/drawer'
const Drawer = createDrawerNavigator()
声明
Drawer.Navigator和Drawer.Screen
Navigator属性
drawerPostion:菜单显示位置,left(默认) | right
drawerType:菜单动画效果,front | back | slide | permanent
drawerStyle: 菜单样式 backgroundColor、width.....
drawerContentOptions:选中菜单项样式 activeTintColor:选中菜单字体颜色 itemStyle:所有菜单样式
Screen的Options属性
title:菜单标题
drawerLabel:替代title,返回复杂的组件。{focused:boolean,color:string}
drawerIcon:返回图标的函数。{focused:boolean,color:string,size:number}
headerShown:是否显示header。布尔型,默认false不显示
headerLeft:函数,声明header左侧的显示内容
headerRight:函数,声明header右侧的显示内容
MaterialTopTap导航,可以滑动的导航
安装
yarn add @react-navigation/material-top-tabs react-native-tab-view
使用
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs'
const Tab = createMaterialTopTabNavigator()
声明 Tab.Navigator和Tab.Screen
Navigator属性
tabBarPosition:Tab显示位置。默认top,可以设置bottom
tabBarOptions:包含tabBar组件属性的对象
activeTintColor-当前菜单的标题或图标颜色
inactiveTintColor-非当前菜单的标题或图标颜色
showIcon-是否显示图标,默认是false
showLabel-是否显示文字,默认是true
tabStyle-标签样式对象
labelStyle-标签文字样式对象,这里指定的颜色,会覆盖activeTintColor和inactiveTintColor的值
iconStyle-图标样式对象
Screen属性
options:设置Screen组件的对象
title-设置显示标题
tabBarIcon-设置标签图标(需要现在Navigator中指定showIcon:true)
其值为函数,包含两个参数{focused:boolean,color:string}
focused用来判断标签是否获取焦点,color为当前标签的颜色
tabBarLabel-设置标签文字内容(当未定义时,会使用title)
其值为函数,包含两个参数:{focused:boolean,color:string}
focused用来判断标签是否获取焦点,color为当前标签的颜色
路由嵌套
在一个导航内部渲染另一个导航
路由传参
传递参数
navigation.navigate('路由名称',{key:123})
接收参数
类组件
this.props.route.key
函数组件
route.params.key
组件库对比:简评4款第三方 React Native 组件库 - 知乎