博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react-native 实现条码扫描(ios&android)
阅读量:4086 次
发布时间:2019-05-25

本文共 19194 字,大约阅读时间需要 63 分钟。

从网上看了很多关于react native实现条码扫描的文章,里面出现了很多第三方库,有的文章说react-native-camera不能支持Android,我就自己试着写写,发现他可以兼容ios和Android。下面就来看看怎么实现吧~http://www.bijishequ.com/detail/379217?p=20

一、新建项目

首先打开终端,在相应的目录下输入命令创建新项目

react-native init CameraDemo

项目创建完成,进入项目根目录下输入命令下载react-native-camera库

1.npm install react-native-camera@https://github.com/lwansbrough/react-native-camera.git --save2.react-native link react-native-camera

二、Android配置

1.打开android/app/src/main/java/[...]/MainApplication.java文件,添加import com.lwansbrough.RCTCamera.RCTCameraPackage;,在getPackages()方法里添加new RCTCameraPackage(),
2.打开android/settings.gradle文件,添加

include ':react-native-camera'project(':react-native-camera').projectDir = new File(rootProject.projectDir,     '../node_modules/react-native-camera/android')

3.打开android/app/build.gradle文件,在dependencies{}中添加compile project(':react-native-camera'
4.在AndroidManifest.xml配置文件中添加相关权限:

//相机权限
//震动权限

注:android配置的前三个步骤一般情况下会自动添加,若没有添加,按上述步骤手动添加!

三、iOS配置

1.使用Xcode打开CameraDemo/ios/CameraDemo.xcodeproj文件,在Project navigator->Libraries文件夹上右击选择Add Files to 'CameraDemo';
2.选择项目中的node_modules->react-native-camera并且添加RCTCamera.xcodeproj文件;
3.在Build Phases中添加libRCTCamera.a;
4.在Build Settings中找到Search Paths下的Header Search Paths,添加$(SRCROOT)/../../react-native/React和$(SRCROOT)/../../../React,并且选择recursive;
如下图:


QQ20170419-140900@2x.png

5.打开ScanDemo/ios/ScanDemo/Info.plist文件,添加下列权限

NSCameraUsageDescription
请允许使用您的相机
NSLocationWhenInUseUsageDescription
NSPhotoLibraryUsageDescription
请允许打开您的相册

注:ios中前三个步骤也会自动加载,若没有添加,需按上述步骤手动添加!

四、编写代码

1.scan.js代码

import React, { Component } from 'react';import { connect } from 'react-redux';import {    View,    Text,    StyleSheet,    Image,    Platform,    Vibration,    TouchableOpacity,    Animated,    Easing,    Dimensions} from 'react-native';const {width, height}  = Dimensions.get('window');import {ToastMessage} from '../../utils/toast';import Camera from 'react-native-camera';import ViewFinder from '../../components/order/viewFinder';import backIcon from '../../../assets/img/backIcon.png';//返回按钮import scanLine from '../../../assets/img/scan_line.png';//扫描线export default class Scan extends Component {    constructor(props) {        super(props);        this.camera = null;        this.state = {            transCode:'',//条码            openFlash: false,            active: true,            flag:true,            fadeInOpacity: new Animated.Value(0), // 初始值            isEndAnimation:false,//结束动画标记        }        this._goBack = this._goBack.bind(this);        this._startAnimation = this._startAnimation.bind(this);        this.barcodeReceived = this.barcodeReceived.bind(this);        this._search = this._search.bind(this);        this._changeFlash = this._changeFlash.bind(this);        this.changeState = this.changeState.bind(this);    }    componentDidMount() {         this._startAnimation(false);    }    //开始动画,循环播放    _startAnimation(isEnd) {        Animated.timing(this.state.fadeInOpacity, {            toValue: 1,            duration: 3000,            easing: Easing.linear        }).start(             () => {                 if (isEnd){                     this.setState({                         isEndAnimation:true                     })                     return;                 }                 if (!this.state.isEndAnimation){                     this.state.fadeInOpacity.setValue(0);                     this._startAnimation(false)                 }             }        );        console.log("开始动画");    }     barcodeReceived(e) {        if (e.data !== this.transCode) {            Vibration.vibrate([0, 500, 200, 500]);            this.transCode = e.data; // 放在this上,防止触发多次,setstate有延时            if(this.state.flag){                this.changeState(false);                //通过条码编号获取数据            }            console.log("transCode="+this.transCode);        }    }     //返回按钮点击事件    _goBack() {        this.setState({            isEndAnimation:true,        });        this.props.navigator.pop();    }    //开灯关灯    _changeFlash() {        this.setState({            openFlash: !this.state.openFlash,        });    }     //改变请求状态    changeState(status){        this.setState({            flag:status        });        console.log('status='+status);    }    render(){        const {                openFlash,                active,            } = this.state;        return(            
{(() => { if (active) { return (
this.camera = cam} style={styles.cameraStyle} barcodeScannerEnabled={true} onBarCodeRead={ this.barcodeReceived } torchMode={openFlash ? 'on' : 'off'}>
将运单上的条码放入框内即可自动扫描。
开灯/关灯
); } })()}
) }}const styles =StyleSheet.create({ allContainer:{ flex:1, }, container: { ...Platform.select({ ios: { height: 64, }, android: { height: 50 } }), backgroundColor:BLACK_COLOR, opacity:0.5 }, titleContainer: { flex: 1, ...Platform.select({ ios: { paddingTop: 15, }, android: { paddingTop: 0, } }), flexDirection: 'row', }, leftContainer: { flex:0, justifyContent: 'center', }, backImg: { marginLeft: 10, }, cameraStyle: { alignSelf: 'center', width: width, height: height, }, flash: { flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-start', marginTop: 60, }, flashIcon: { fontSize: 1, color: WHITE_COLOR, }, text: { fontSize: 14, color: WHITE_COLOR, marginTop:5 }, icon:{ color:WHITE_COLOR, fontSize:20, fontFamily:'iconfont' }, scanLine:{ alignSelf:'center', }, centerContainer:{ ...Platform.select({ ios: { height: 80, }, android: { height: 60, } }), width:width, backgroundColor:BLACK_COLOR, opacity:0.5 }, bottomContainer:{ alignItems:'center', backgroundColor:BLACK_COLOR, alignSelf:'center', opacity:0.5, flex:1, width:width }, fillView:{ width:(width-220)/2, height:220, backgroundColor:BLACK_COLOR, opacity:0.5 }, scan:{ width:220, height:220, alignSelf:'center' }})

2.viewFinder.js代码

import React, {  Component,  PropTypes,} from 'react';import {  ActivityIndicator,  StyleSheet,  View,} from 'react-native';const styles = StyleSheet.create({  container: {    alignItems: 'center',    justifyContent: 'center',    position: 'absolute',    top: 0,    right: 0,    bottom: 0,    left: 0,  },  viewfinder: {    alignItems: 'center',    justifyContent: 'center',    backgroundColor: 'transparent',  },  topLeftEdge: {    position: 'absolute',    top: 0,    left: 0,  },  topRightEdge: {    position: 'absolute',    top: 0,    right: 0,  },  bottomLeftEdge: {    position: 'absolute',    bottom: 0,    left: 0,  },  bottomRightEdge: {    position: 'absolute',    bottom: 0,    right: 0,  },});class Viewfinder extends Component {  constructor(props) {    super(props);    this.getBackgroundColor = this.getBackgroundColor.bind(this);    this.getSizeStyles = this.getSizeStyles.bind(this);    this.getEdgeSizeStyles = this.getEdgeSizeStyles.bind(this);    this.renderLoadingIndicator = this.renderLoadingIndicator.bind(this);  }  getBackgroundColor() {    return ({      backgroundColor: this.props.backgroundColor,    });  }  getEdgeColor() {    return ({      borderColor: this.props.color,    });  }  getSizeStyles() {    return ({      height: this.props.height,      width: this.props.width,    });  }  getEdgeSizeStyles() {    return ({      height: this.props.borderLength,      width: this.props.borderLength,    });  }  renderLoadingIndicator() {    if (!this.props.isLoading) {      return null;    }    return (      
); }render() { return (
{this.renderLoadingIndicator()}
); }}Viewfinder.propTypes = { backgroundColor: PropTypes.string, borderWidth: PropTypes.number, borderLength: PropTypes.number, color: PropTypes.string, height: PropTypes.number, isLoading: PropTypes.bool, width: PropTypes.number,};Viewfinder.defaultProps = { backgroundColor: 'transparent', borderWidth: 3, borderLength: 20, color: COLOR_MAIN, height: 220, isLoading: false, width: 220,};module.exports = Viewfinder;

大功告成~最后上张效果图:

http://www.bijishequ.com/detail/379217?p=20

一、新建项目

首先打开终端,在相应的目录下输入命令创建新项目

react-native init CameraDemo

项目创建完成,进入项目根目录下输入命令下载react-native-camera库

1.npm install react-native-camera@https://github.com/lwansbrough/react-native-camera.git --save2.react-native link react-native-camera

二、Android配置

1.打开android/app/src/main/java/[...]/MainApplication.java文件,添加import com.lwansbrough.RCTCamera.RCTCameraPackage;,在getPackages()方法里添加new RCTCameraPackage(),
2.打开android/settings.gradle文件,添加

include ':react-native-camera'project(':react-native-camera').projectDir = new File(rootProject.projectDir,     '../node_modules/react-native-camera/android')

3.打开android/app/build.gradle文件,在dependencies{}中添加compile project(':react-native-camera'
4.在AndroidManifest.xml配置文件中添加相关权限:

//相机权限
//震动权限

注:android配置的前三个步骤一般情况下会自动添加,若没有添加,按上述步骤手动添加!

三、iOS配置

1.使用Xcode打开CameraDemo/ios/CameraDemo.xcodeproj文件,在Project navigator->Libraries文件夹上右击选择Add Files to 'CameraDemo';
2.选择项目中的node_modules->react-native-camera并且添加RCTCamera.xcodeproj文件;
3.在Build Phases中添加libRCTCamera.a;
4.在Build Settings中找到Search Paths下的Header Search Paths,添加$(SRCROOT)/../../react-native/React和$(SRCROOT)/../../../React,并且选择recursive;
如下图:


QQ20170419-140900@2x.png

5.打开ScanDemo/ios/ScanDemo/Info.plist文件,添加下列权限

NSCameraUsageDescription
请允许使用您的相机
NSLocationWhenInUseUsageDescription
NSPhotoLibraryUsageDescription
请允许打开您的相册

注:ios中前三个步骤也会自动加载,若没有添加,需按上述步骤手动添加!

四、编写代码

1.scan.js代码

import React, { Component } from 'react';import { connect } from 'react-redux';import {    View,    Text,    StyleSheet,    Image,    Platform,    Vibration,    TouchableOpacity,    Animated,    Easing,    Dimensions} from 'react-native';const {width, height}  = Dimensions.get('window');import {ToastMessage} from '../../utils/toast';import Camera from 'react-native-camera';import ViewFinder from '../../components/order/viewFinder';import backIcon from '../../../assets/img/backIcon.png';//返回按钮import scanLine from '../../../assets/img/scan_line.png';//扫描线export default class Scan extends Component {    constructor(props) {        super(props);        this.camera = null;        this.state = {            transCode:'',//条码            openFlash: false,            active: true,            flag:true,            fadeInOpacity: new Animated.Value(0), // 初始值            isEndAnimation:false,//结束动画标记        }        this._goBack = this._goBack.bind(this);        this._startAnimation = this._startAnimation.bind(this);        this.barcodeReceived = this.barcodeReceived.bind(this);        this._search = this._search.bind(this);        this._changeFlash = this._changeFlash.bind(this);        this.changeState = this.changeState.bind(this);    }    componentDidMount() {         this._startAnimation(false);    }    //开始动画,循环播放    _startAnimation(isEnd) {        Animated.timing(this.state.fadeInOpacity, {            toValue: 1,            duration: 3000,            easing: Easing.linear        }).start(             () => {                 if (isEnd){                     this.setState({                         isEndAnimation:true                     })                     return;                 }                 if (!this.state.isEndAnimation){                     this.state.fadeInOpacity.setValue(0);                     this._startAnimation(false)                 }             }        );        console.log("开始动画");    }     barcodeReceived(e) {        if (e.data !== this.transCode) {            Vibration.vibrate([0, 500, 200, 500]);            this.transCode = e.data; // 放在this上,防止触发多次,setstate有延时            if(this.state.flag){                this.changeState(false);                //通过条码编号获取数据            }            console.log("transCode="+this.transCode);        }    }     //返回按钮点击事件    _goBack() {        this.setState({            isEndAnimation:true,        });        this.props.navigator.pop();    }    //开灯关灯    _changeFlash() {        this.setState({            openFlash: !this.state.openFlash,        });    }     //改变请求状态    changeState(status){        this.setState({            flag:status        });        console.log('status='+status);    }    render(){        const {                openFlash,                active,            } = this.state;        return(            
{(() => { if (active) { return (
this.camera = cam} style={styles.cameraStyle} barcodeScannerEnabled={true} onBarCodeRead={ this.barcodeReceived } torchMode={openFlash ? 'on' : 'off'}>
将运单上的条码放入框内即可自动扫描。
开灯/关灯
); } })()}
) }}const styles =StyleSheet.create({ allContainer:{ flex:1, }, container: { ...Platform.select({ ios: { height: 64, }, android: { height: 50 } }), backgroundColor:BLACK_COLOR, opacity:0.5 }, titleContainer: { flex: 1, ...Platform.select({ ios: { paddingTop: 15, }, android: { paddingTop: 0, } }), flexDirection: 'row', }, leftContainer: { flex:0, justifyContent: 'center', }, backImg: { marginLeft: 10, }, cameraStyle: { alignSelf: 'center', width: width, height: height, }, flash: { flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-start', marginTop: 60, }, flashIcon: { fontSize: 1, color: WHITE_COLOR, }, text: { fontSize: 14, color: WHITE_COLOR, marginTop:5 }, icon:{ color:WHITE_COLOR, fontSize:20, fontFamily:'iconfont' }, scanLine:{ alignSelf:'center', }, centerContainer:{ ...Platform.select({ ios: { height: 80, }, android: { height: 60, } }), width:width, backgroundColor:BLACK_COLOR, opacity:0.5 }, bottomContainer:{ alignItems:'center', backgroundColor:BLACK_COLOR, alignSelf:'center', opacity:0.5, flex:1, width:width }, fillView:{ width:(width-220)/2, height:220, backgroundColor:BLACK_COLOR, opacity:0.5 }, scan:{ width:220, height:220, alignSelf:'center' }})

2.viewFinder.js代码

import React, {  Component,  PropTypes,} from 'react';import {  ActivityIndicator,  StyleSheet,  View,} from 'react-native';const styles = StyleSheet.create({  container: {    alignItems: 'center',    justifyContent: 'center',    position: 'absolute',    top: 0,    right: 0,    bottom: 0,    left: 0,  },  viewfinder: {    alignItems: 'center',    justifyContent: 'center',    backgroundColor: 'transparent',  },  topLeftEdge: {    position: 'absolute',    top: 0,    left: 0,  },  topRightEdge: {    position: 'absolute',    top: 0,    right: 0,  },  bottomLeftEdge: {    position: 'absolute',    bottom: 0,    left: 0,  },  bottomRightEdge: {    position: 'absolute',    bottom: 0,    right: 0,  },});class Viewfinder extends Component {  constructor(props) {    super(props);    this.getBackgroundColor = this.getBackgroundColor.bind(this);    this.getSizeStyles = this.getSizeStyles.bind(this);    this.getEdgeSizeStyles = this.getEdgeSizeStyles.bind(this);    this.renderLoadingIndicator = this.renderLoadingIndicator.bind(this);  }  getBackgroundColor() {    return ({      backgroundColor: this.props.backgroundColor,    });  }  getEdgeColor() {    return ({      borderColor: this.props.color,    });  }  getSizeStyles() {    return ({      height: this.props.height,      width: this.props.width,    });  }  getEdgeSizeStyles() {    return ({      height: this.props.borderLength,      width: this.props.borderLength,    });  }  renderLoadingIndicator() {    if (!this.props.isLoading) {      return null;    }    return (      
); }render() { return (
{this.renderLoadingIndicator()}
); }}Viewfinder.propTypes = { backgroundColor: PropTypes.string, borderWidth: PropTypes.number, borderLength: PropTypes.number, color: PropTypes.string, height: PropTypes.number, isLoading: PropTypes.bool, width: PropTypes.number,};Viewfinder.defaultProps = { backgroundColor: 'transparent', borderWidth: 3, borderLength: 20, color: COLOR_MAIN, height: 220, isLoading: false, width: 220,};module.exports = Viewfinder;

大功告成~最后上张效果图:

转载地址:http://qwrni.baihongyu.com/

你可能感兴趣的文章
《多旋翼无人飞行器嵌入式飞控开发指南》里基于FreeRTOS的无人机软件框架
查看>>
思岚A1的SDK其实很好读懂,每个函数清晰明了,可以直接调用
查看>>
pixhawk(PX4)的一些论坛网站(包括中文版的PX4用户手册和PX4开发手册)
查看>>
串级 PID 为什么外环输出是内环的期望?(和我之前对串级PID的总结一样)
查看>>
我刚刚才完全清楚GPS模块的那根杆子是怎么固定安装好的
查看>>
去github里面找找也没有别人无人机+SLAM的工程
查看>>
PX4与ROS关系以及仿真控制(键盘控制无人机)
查看>>
我对无人机重心高度的理解
查看>>
现在明白为什么无名博客里好几篇文章在讲传感器的滞后
查看>>
实际我看Pixhawk定高模式其实也是飞得很稳,飘得也不厉害
查看>>
Pixhawk解锁常见错误
查看>>
C++的模板化等等的确实比C用起来方便多了
查看>>
ROS是不是可以理解成一个虚拟机,就是操作系统之上的操作系统
查看>>
用STL algorithm轻松解决几道算法面试题
查看>>
ACfly之所以不怕炸机因为它觉得某个传感器数据不安全就立马不用了
查看>>
我发觉,不管是弄ROS OPENCV T265二次开发 SDK开发 caffe PX4 都是用的C++
查看>>
ROS的安装(包含文字和视频教程,我的ROS安装教程以这篇为准)
查看>>
国内有个码云,gitee
查看>>
原来我之前一直用的APM固件....现在很多东西明白了。
查看>>
realsense-ros里里程计相关代码
查看>>