目录:
- 思路
- 安装中间件
- 确认
iOS
、Android
配置信息 - 封装扫码组件
- 另一个组件获取扫码数据
思路
- 安装中间件
react-native-camera
; - 检查
iOS
、Android
是否配置成功; - 封装扫码组件,实现页面布局、扫码动画、获取扫描信息等;
- 另一个组件添加扫码入口,获取扫码数据;
具体步骤
1. 安装中间件 react-native-camera
,参考官网
版本:
"react": "16.8.3",
"react-native": "0.59.9",
"react-native-camera": "2.10.2"
安装方式:
npm install react-native-camera --save
react-native link react-native-camera
2.可能 link
失败,检查 iOS
、Android
是否配置成功
iOS
环境:
- 【检查】是否存在 `RNCamera.xcodeproj`
用 XCode 打开 iOS 项目/Libraries/RNCamera.xcodeproj;
若不存在:右键Libraries->add Files to xxx项目名
-> 选择RN项目中node_modules -> react-native-camera -> 确定
- 【检查】是否有相机使用权限
在 `info.plist` 中添加相机使用权限 key:
"Privacy - Camera Usage Description",value: "需要您的同意才能使用相机"
Android
环境:
- 【检查】`android/app/src/main/java/com/xxx/MainApplication.java`
+ import org.reactnative.camera.RNCameraPackage;
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
+ new RNCameraPackage()
);
}
- 【检查】android/settings.gradle
+ include ':react-native-camera'
+ project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
- 【检查】android/app/build.gradle
android {
...
defaultConfig {
...
+ missingDimensionStrategy 'react-native-camera', 'general'
}
}
...
dependencies {
+ implementation project(':react-native-camera')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation "com.facebook.react:react-native:+" // From node_modules
}
- 【检查】android/build.gradle
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
maven { url "https://maven.google.com" }
}
}
- 【检查】android/app/src/main/AndroidManifest.xml 是否有相机使用相关权限
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- 配置文件 android/build.gradle 版本信息如下
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
supportLibVersion = "28.0.0"
}
repositories {
google()
jcenter()
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
classpath("com.android.tools.build:gradle:3.4.0")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
google()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
maven { url "https://jitpack.io" }
maven { url "https://maven.google.com" }
}
}
- 以上配置完毕,如果有报错,可以选择关闭开发工具,重新打开,本人就是一样的操作,昨天出现各种错误,今天从头再一样到配置,就可以了,嗨,生活
3、封装扫码组件,实现页面布局、扫码动画、获取扫描信息
【封装】扫码组件 BarCodePage;
注意:扫码成功后跳转到 TestPage 页面;
import React, { Component } from 'react';
import {
View,
StyleSheet,
Text,
Animated,
Easing,
InteractionManager,
TouchableOpacity,
Image,
SafeAreaView,
Dimensions
} from 'react-native';
import { RNCamera } from 'react-native-camera';
const { width, height } = Dimensions.get('window');
const Height = () => {
return height
};
const Width = () => {
return width
};
class BarCodePage extends Component {
constructor(props) {
super(props);
this.state = {
transCode:'', // 条码
typeCode: '', // 条码类型
showCode: true,
animateCode: new Animated.Value((Width() - 200) / 2,(Height() - 340) / 2), // 二维坐标
}
}
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
this.startAnimation()
})
console.log('进入-------', this.state.showCode)
}
// 动画开始
startAnimation() {
this.state.animateCode.setValue(0)
Animated.timing(this.state.animateCode, {
toValue: 1, // 运动终止位置,比值
duration: 2500, // 动画时长
easing: Easing.linear, // 线性的渐变函数
delay: 0.3, // 在一段时间之后开始动画(单位是毫秒),默认为0
}).start(() => this.startAnimation())
}
barcodeReceived(e) {
let that = this
if(this.state.showCode){
console.log(e);
that.setState({
transCode: e.data,
typeCode: e.type,
showCode: false
})
if(e.data) {
let barCodeData = {
typeName: 'testScan', // TestPage获取此值
typeValue: e.data
}
that.props.navigation.navigate('TestPage', { barCodeData })
}
}
}
// 关闭扫一扫
closeScanPage() {
this.props.navigation.navigate('TestPage')
}
render() {
return (
<View style={styles.container}>
<SafeAreaView style={styles.container}>
<RNCamera
onBarCodeRead={this.barcodeReceived.bind(this)}
onCameraReady={() => {
console.log('ready')
}}
permissionDialogTitle={'提示信息'}
permissionDialogMessage={'APP需要使用相机,请打开相机权限允许APP使用'}
style={styles.scan_camera}
>
<View style={styles.scan_cont_box}>
<View style={styles.scan_cont_circle}>
<Animated.View style={{
alignItems: 'center',
transform: [{
// translateX: x轴移动
// translateY: y轴移动
translateY: this.state.animateCode.interpolate({
inputRange: [0,1],
outputRange: [0,200]
})
}]
}}>
<Text style={styles.scan_circle_init}></Text>
</Animated.View>
</View>
</View>
<TouchableOpacity
activeOpacity={.8}
style={styles.scan_top_box}
onPress={() => this.closeScanPage()}
>
<Image source={require('关闭图标,不需要可删除.png')}/>
</TouchableOpacity>
<View style={styles.scan_info_box}>
<Text style={styles.scan_info}>将条形码放入框内,即可自动扫描</Text>
</View>
</RNCamera>
</SafeAreaView>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
scan_top_box: {
position: "absolute",
left: 20,
top: 20,
width: 24,
height: 24
},
scan_camera: {
flex: 1,
height: Height()
},
scan_cont_box: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0,0,0,0.3)',
},
scan_cont_circle: {
width: 260,
height: 260,
borderWidth: 1,
borderColor: '#919191',
backgroundColor: 'rgba(255,255,255,0.1)'
},
scan_circle_init: {
width:250,
height:1,
backgroundColor:'#00ff00'
},
scan_info_box: {
height: 100,
backgroundColor: 'rgba(0,0,0,0.3)',
alignItems: 'center',
width: Width()
},
scan_info: {
color: '#fff'
},
info: {
width: Width(),
height: 80,
backgroundColor: '#fff',
paddingLeft: 10,
paddingBottom:5,
justifyContent: 'space-around',
},
})
export default BarCodePage;
4、TestPage
页面增加入口,以及获取扫描的信息,结束✌️
`TestPage`主要代码如下:
constructor(props) {
super(props);
this.state = {
inputValue: ''
}
}
componentWillReceiveProps(nextProps) {
// 监听扫码页面获取的值
let { barCodeData } = nextProps.navigation.state.params
let that = this
if(barCodeData && barCodeData.typeValue && barCodeData.typeName == 'testScan') {
that.setState({
inputValue: barCodeData.typeValue
})
}
}
handleScanCheck() {
this.props.navigation.navigate('BarCodePage')
}
render() {
let { inputValue } = this.state
return(
<Text>展示条形码数据:</Text>
<TextInput defaultValue={inputValue} />
<TouchableOpacity
activeOpacity={.8}
onPress={() => this.handleScanCheck()}
>
<Image source={require('扫一扫图标,点击进入扫码页面.png')} />
</TouchableOpacity>
)
}
写给自己的随笔,有问题欢迎指出