Giter Site home page Giter Site logo

marnodev / react-native-qrcode-scanner-view Goto Github PK

View Code? Open in Web Editor NEW
691.0 18.0 220.0 22.97 MB

A highly customizable QR code scanning component for React Native

License: Apache License 2.0

JavaScript 100.00%
react-native react-native-component reactjs android ios hybird

react-native-qrcode-scanner-view's Introduction

react-native-qrcode-scanner-view

A highly customized qrcode viewfinder base on react-native-camera. You must set up react-native-camera correctly first before use it.If you need to set more react-native-camera props, you can just use Viewfinder which is exported as QRScannerRectView. Please view source code to learn more.


Guide

Features

  • Pure JS code
  • Support Android and iOS
  • Support React Native 0.60+
  • Support scan QR code, Bar code
  • Scanning interface can be customized

ScreenShots

Default WeChat MeiTuan
TikTok DemoHome Demo Gif

Installation

// First
set up react-native-camera

// Second
yarn add react-native-qrcode-scanner-view

// or

npm install react-native-qrcode-scanner-view --save

Basic

import { View } from 'react-native';
import { QRScannerView } from 'react-native-qrcode-scanner-view';

export default class DefaultScreen extends Component {

    renderTitleBar = () => <Text style={{color:'white',textAlign:'center',padding:16}}>Title</Text>

    renderMenu = () => <Text style={{color:'white',textAlign:'center',padding:16}}>Menu</Text>

    barcodeReceived = (event) => { console.log('Type: ' + event.type + '\nData: ' + event.data) };

    render() {
        return (
           <View style={{flex:1}}>
            < QRScannerView
                onScanResult={ this.barcodeReceived }
                renderHeaderView={ this.renderTitleBar }
                renderFooterView={ this.renderMenu }
                scanBarAnimateReverse={ true }/>
           </View>
        )
    }
}

Props

Prop Type Default Optional
maskColor string #0000004D true
rectStyle object height: 300,
width: 300,
borderWidth: 0,
borderColor: '#000000',
marginBottom: 0
true
cornerStyle object height: 32,
width: 32,
borderWidth: 6,
borderColor: '#1A6DD5'
true
cornerOffsetSize number 0 true
isShowCorner bool true true
scanBarStyle object marginHorizontal: 8,
borderRadius: 2,
backgroundColor: '#1A6DD5'
true
isShowScanBar bool true true
scanBarAnimateTime number 3000 true
scanBarAnimateReverse bool false true
scanBarImage any true
hintText string true
hintTextStyle object color: '#fff',
fontSize: 14,
backgroundColor: 'transparent',
marginTop: 32
true
renderHeaderView func - true
renderFooterView func - true
onScanResult func - false
scanInterval number 2000 true
torchOn bool false true
userFront bool false true

About

react-native-qrcode-scanner-view's People

Contributors

dependabot[bot] avatar ethanlin-twer avatar ewelohd avatar geek-ch avatar marnodev avatar yeomanye avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-qrcode-scanner-view's Issues

扫码时,很容易识别扫码框以外的二维码

RT,扫码的时候,可以识别,而且速度很快,但是如果一个单子上面有两个二维码,很容易就误识别了。
经常会识别扫码框以外的二维码,但是并不是自己想要扫的,这样体验很不好

大bug,扫描退出后无法执行InteractionManager.runAfterInteractions

从扫描页面退出后,如果下一个页面有调用InteractionManager.runAfterInteractions方法,会由于扫描组件内的动画一直循环而无法执行,只需要在添加isInteraction: false即可,希望作者可以加一下
scannerLineMove() {
this.state.animatedValue.setValue(0); //重置Rotate动画值为0
Animated.timing(this.state.animatedValue, {
toValue: this.props.rectHeight,
duration: this.props.scanBarAnimateTime,
easing: Easing.linear,
isInteraction: false
}).start(() => this.scannerLineMove());
}

扫描框位置

您好,请问扫描框位置怎么调整,我想把扫描框往上移一些

闪退

您好,我像请教个问题,反复进入二维码页面时,程序会闪退,这个有什么好的解决办法吗。

run device error

error undefined is not an object(evaluating '_reat2.ProTypes.oneOfType')
when i install it that can not run. it is a error!
version
"react": "16.0.0-beta.5", "react-native": "0.49.3",

需要怎么配置?

我想把你这个用到我的项目中,但是不太清楚要怎么改动项目中的哪些配置文件?您能帮我说一下么

当跳转扫描页面的时候中间那根条还是在滚动.. 定时器还是在跑... 有好办法吗

/**

  • Created by marno on 2017/4/13
  • Function: 二维码扫描界面
  • Desc:
    */
    import React, {Component} from 'react';
    import Camera from 'react-native-camera';
    import
    {
    ActivityIndicator,
    StyleSheet,
    View,
    Animated,
    Easing,
    Text,
    Image
    } from 'react-native';

/**

  • 扫描界面遮罩

  • 单独写一个类,方便拷贝使用
    */
    class QRScannerRectView extends Component {
    static defaultProps = {
    maskColor: '#0000004D',
    cornerColor: '#22ff00',
    borderColor: '#000000',
    rectHeight: 200,
    rectWidth: 200,
    borderWidth: 0,
    cornerBorderWidth: 4,
    cornerBorderLength: 20,
    isLoading: false,
    cornerOffsetSize: 0,
    isCornerOffset: false,
    bottomMenuHeight: 0,
    scanBarAnimateTime: 2500,
    scanBarColor: '#22ff00',
    scanBarImage: null,
    scanBarHeight: 1.5,
    scanBarMargin: 6,
    hintText: '将二维码/条码放入框内,即可自动扫描',
    hintTextStyle: {color: '#fff', fontSize: 14,backgroundColor:'transparent'},
    hintTextPosition: 130,
    isShowScanBar:true
    };

    constructor(props) {
    super(props);

     this.getBackgroundColor = this.getBackgroundColor.bind(this);
     this.getRectSize = this.getRectSize.bind(this);
     this.getCornerSize = this.getCornerSize.bind(this);
     this.renderLoadingIndicator = this.renderLoadingIndicator.bind(this);
    
     this.state = {
         topWidth: 0,
         topHeight: 0,
         leftWidth: 0,
         animatedValue: new Animated.Value(0),
         scanning: true
     }
    

    }

    //获取背景颜色
    getBackgroundColor() {
    return ({
    backgroundColor: this.props.maskColor,
    });
    }

    //获取扫描框背景大小
    getRectSize() {
    return ({
    height: this.props.rectHeight,
    width: this.props.rectWidth,
    });
    }

    //获取扫描框边框大小
    getBorderSize() {
    if (this.props.isCornerOffset) {
    return ({
    height: this.props.rectHeight - this.props.cornerOffsetSize * 2,
    width: this.props.rectWidth - this.props.cornerOffsetSize * 2,
    });
    } else {
    return ({
    height: this.props.rectHeight,
    width: this.props.rectWidth,
    });
    }
    }

    //获取扫描框转角的颜色
    getCornerColor() {
    return ({
    borderColor: this.props.cornerColor,
    });
    }

    //获取扫描框转角的大小
    getCornerSize() {
    return ({
    height: this.props.cornerBorderLength,
    width: this.props.cornerBorderLength,
    });
    }

    //获取扫描框大小
    getBorderWidth() {
    return ({
    borderWidth: this.props.borderWidth,
    });
    }

    //获取扫描框颜色
    getBorderColor() {
    return ({
    borderColor: this.props.borderColor,
    });
    }

    //渲染加载动画
    renderLoadingIndicator() {
    if (!this.props.isLoading) {
    return null;
    }

     return (
         <ActivityIndicator
             animating={this.props.isLoading}
             color={this.props.color}
             size='large'
         />
     );
    

    }

    //测量整个扫描组件的大小
    measureTotalSize(e) {
    let totalSize = e.layout;
    this.setState({
    topWidth: totalSize.width,
    })
    }

    //测量扫描框的位置
    measureRectPosition(e) {
    let rectSize = e.layout;
    this.setState({
    topHeight: rectSize.y,
    leftWidth: rectSize.x,
    })
    }

    //获取顶部遮罩高度
    getTopMaskHeight() {
    if (this.props.isCornerOffset) {
    return this.state.topHeight + this.props.rectHeight - this.props.cornerOffsetSize;
    } else {
    return this.state.topHeight + this.props.rectHeight;
    }
    }

    //获取底部遮罩高度
    getBottomMaskHeight() {
    if (this.props.isCornerOffset) {
    return this.props.rectHeight + this.state.topHeight - this.props.cornerOffsetSize;
    } else {
    return this.state.topHeight + this.props.rectHeight;
    }
    }

    //获取左右两边遮罩高度
    getSideMaskHeight() {
    if (this.props.isCornerOffset) {
    return this.props.rectHeight - this.props.cornerOffsetSize * 2;
    } else {
    return this.props.rectHeight;
    }
    }

    //获取左右两边遮罩宽度
    getSideMaskWidth() {
    if (this.props.isCornerOffset) {
    return this.state.leftWidth + this.props.cornerOffsetSize;
    } else {
    return this.state.leftWidth;
    }
    }

    getBottomMenuHeight() {
    return ({
    bottom: this.props.bottomMenuHeight,
    });
    }

    getScanBarMargin() {
    return ({
    marginRight: this.props.scanBarMargin,
    marginLeft: this.props.scanBarMargin,
    })
    }

    getScanImageWidth() {
    return this.props.rectWidth - this.props.scanBarMargin * 2
    }

    //绘制扫描线
    _renderScanBar() {
    if(!this.props.isShowScanBar) return;
    if (this.props.scanBarImage) {
    return <Image style={ {resizeMode: 'contain', width: this.getScanImageWidth()}}
    source={this.props.scanBarImage}/>
    } else {
    return <View style={[this.getScanBarMargin(), {
    backgroundColor: this.props.scanBarColor,
    height: this.props.scanBarHeight,
    }]}/>
    }
    }

    render() {
    const animatedStyle = {
    transform: [
    {translateY: this.state.animatedValue}
    ]
    };

     return (
         <View
             onLayout={({nativeEvent: e}) => this.measureTotalSize(e)}
             style={[styles.container, this.getBottomMenuHeight()]}>
    
             <View style={[styles.viewfinder, this.getRectSize()]}
                   onLayout={({nativeEvent: e}) => this.measureRectPosition(e)}
             >
    
                 {/*扫描框边线*/}
                 <View style={[
                     this.getBorderSize(),
                     this.getBorderColor(),
                     this.getBorderWidth(),
                 ]}>
    
                     <Animated.View
                         style={[
                             animatedStyle,]}>
                         {this._renderScanBar()}
                     </Animated.View>
    
                 </View>
    
                 {/*扫描框转角-左上角*/}
                 <View style={[
                     this.getCornerColor(),
                     this.getCornerSize(),
                     styles.topLeftCorner,
                     {
                         borderLeftWidth: this.props.cornerBorderWidth,
                         borderTopWidth: this.props.cornerBorderWidth,
                     }
                 ]}/>
    
                 {/*扫描框转角-右上角*/}
                 <View style={[
                     this.getCornerColor(),
                     this.getCornerSize(),
                     styles.topRightCorner,
                     {
                         borderRightWidth: this.props.cornerBorderWidth,
                         borderTopWidth: this.props.cornerBorderWidth,
                     }
                 ]}/>
    
                 {/*加载动画*/}
                 {this.renderLoadingIndicator()}
    
                 {/*扫描框转角-左下角*/}
                 <View style={[
                     this.getCornerColor(),
                     this.getCornerSize(),
                     styles.bottomLeftCorner,
                     {
                         borderLeftWidth: this.props.cornerBorderWidth,
                         borderBottomWidth: this.props.cornerBorderWidth,
                     }
                 ]}/>
    
                 {/*扫描框转角-右下角*/}
                 <View style={[
                     this.getCornerColor(),
                     this.getCornerSize(),
                     styles.bottomRightCorner,
                     {
                         borderRightWidth: this.props.cornerBorderWidth,
                         borderBottomWidth: this.props.cornerBorderWidth,
                     }
                 ]}/>
             </View>
    
             <View style={[
                 this.getBackgroundColor(),
                 styles.topMask,
                 {
                     bottom: this.getTopMaskHeight(),
                     width: this.state.topWidth,
                 }
             ]}/>
    
             <View style={[
                 this.getBackgroundColor(),
                 styles.leftMask,
                 {
                     height: this.getSideMaskHeight(),
                     width: this.getSideMaskWidth(),
                 }
             ]}/>
    
             <View style={[
                 this.getBackgroundColor(),
                 styles.rightMask,
                 {
                     height: this.getSideMaskHeight(),
                     width: this.getSideMaskWidth(),
                 }]}/>
    
             <View style={[
                 this.getBackgroundColor(),
                 styles.bottomMask,
                 {
                     top: this.getBottomMaskHeight(),
                     width: this.state.topWidth,
                 }]}/>
    
             <View style={{position: 'absolute', bottom: this.props.hintTextPosition}}>
                 <Text style={this.props.hintTextStyle}>{this.props.hintText}</Text>
             </View>
    
         </View>
     );
    

    }

    componentDidMount() {
    this.scannerLineMove();
    scaning = true;
    }

    componentWillUnmount() {
    scaning = false;
    }

    scannerLineMove() {
    this.state.animatedValue.setValue(0); //重置Rotate动画值为0
    Animated.timing(this.state.animatedValue, {
    toValue: this.props.rectHeight,
    duration: this.props.scanBarAnimateTime,
    easing: Easing.linear
    }).start(() => {
    if(scaning){
    this.scannerLineMove();
    }
    });
    }
    }
    // 全局变量 定义是否退出循环调用 不然会导致内存泄露
    let scaning = true;
    /**

  • 扫描界面
    */
    export default class QRScannerView extends Component {
    static propTypes = {
    maskColor: React.PropTypes.string,
    borderColor: React.PropTypes.string,
    cornerColor: React.PropTypes.string,
    borderWidth: React.PropTypes.number,
    cornerBorderWidth: React.PropTypes.number,
    cornerBorderLength: React.PropTypes.number,
    rectHeight: React.PropTypes.number,
    rectWidth: React.PropTypes.number,
    isLoading: React.PropTypes.bool,
    isCornerOffset: React.PropTypes.bool,//边角是否偏移
    cornerOffsetSize: React.PropTypes.number,
    bottomMenuHeight: React.PropTypes.number,
    scanBarAnimateTime: React.PropTypes.number,
    scanBarColor: React.PropTypes.string,
    scanBarImage: React.PropTypes.any,
    scanBarHeight: React.PropTypes.number,
    scanBarMargin: React.PropTypes.number,
    hintText: React.PropTypes.string,
    hintTextStyle: React.PropTypes.object,
    hintTextPosition:React.PropTypes.number,
    renderTopBarView:React.PropTypes.func,
    renderBottomMenuView:React.PropTypes.func,
    isShowScanBar:React.PropTypes.bool,
    bottomMenuStyle:React.PropTypes.object,
    };

    constructor(props) {
    super(props);
    //通过这句代码屏蔽 YellowBox
    console.disableYellowBox = true;
    }

    render() {
    return (
    <View style={{flex: 1}}>
    <Camera
    onBarCodeRead={this.props.onScanResultReceived}
    style={{flex: 1}}
    >
    {/绘制顶部标题栏组件/}
    {this.props.renderTopBarView()}

                 {/*绘制扫描遮罩*/}
                 <QRScannerRectView
                     maskColor={this.props.maskColor}
                     cornerColor={this.props.cornerColor}
                     borderColor={this.props.borderColor}
                     rectHeight={this.props.rectHeight}
                     rectWidth={this.props.rectWidth}
                     borderWidth={this.props.borderWidth}
                     cornerBorderWidth={this.props.cornerBorderWidth}
                     cornerBorderLength={this.props.cornerBorderLength}
                     isLoading={this.props.isLoading}
                     cornerOffsetSize={this.props.cornerOffsetSize}
                     isCornerOffset={this.props.isCornerOffset}
                     bottomMenuHeight={this.props.bottomMenuHeight}
                     scanBarAnimateTime={this.props.scanBarAnimateTime}
                     scanBarColor={this.props.scanBarColor}
                     scanBarHeight={this.props.scanBarHeight}
                     scanBarMargin={this.props.scanBarMargin}
                     hintText={this.props.hintText}
                     hintTextStyle={this.props.hintTextStyle}
                     scanBarImage={this.props.scanBarImage}
                     hintTextPosition={this.props.hintTextPosition}
                     isShowScanBar={this.props.isShowScanBar}
                 />
    
                 {/*绘制底部操作栏*/}
                 <View style={[styles.buttonsContainer, this.props.bottomMenuStyle]}>
                     {this.props.renderBottomMenuView()}
                 </View>
    
             </Camera>
         </View>
     );
    

    }
    }

const styles = StyleSheet.create({
buttonsContainer: {
position: 'absolute',
height: 100,
bottom: 0,
left: 0,
right: 0,
},
container: {
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
top: 0,
right: 0,
left: 0,
},
viewfinder: {
alignItems: 'center',
justifyContent: 'center',
},
topLeftCorner: {
position: 'absolute',
top: 0,
left: 0,
},
topRightCorner: {
position: 'absolute',
top: 0,
right: 0,
},
bottomLeftCorner: {
position: 'absolute',
bottom: 0,
left: 0,
},
bottomRightCorner: {
position: 'absolute',
bottom: 0,
right: 0,
},
topMask: {
position: 'absolute',
top: 0,
},
leftMask: {
position: 'absolute',
left: 0,
},
rightMask: {
position: 'absolute',
right: 0,
},
bottomMask: {
position: 'absolute',
bottom: 0,
}
});

Cannot read property 'oneOfType' of undefined

启动报错,怀疑依赖没有更新到最新版本

错误堆栈如下:
Cannot read property 'oneOfType' of undefined

C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\ac-qrcode\node_modules\react-native-camera\index.js:75:22
loadModuleImplementation
C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\metro-bundler\src\Resolver\polyfills\require.js:191:4
guardedLoadModule
C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\metro-bundler\src\Resolver\polyfills\require.js:138:11
_require
C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\metro-bundler\src\Resolver\polyfills\require.js:118:2

C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\ac-qrcode\QRScanner.js:7
loadModuleImplementation
C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\metro-bundler\src\Resolver\polyfills\require.js:191:4
guardedLoadModule
C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\metro-bundler\src\Resolver\polyfills\require.js:138:11
_require
C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\metro-bundler\src\Resolver\polyfills\require.js:118:2

C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\ac-qrcode\index.js:7
loadModuleImplementation
C:\Users\yeming\Desktop\RN\mcloud-h5\node_modules\metro-bundler\src\Resolver\polyfills\require.js:191:4

Old version being added in node modules

When I install this module using NPM, an older version is added to my node modules that uses React.PropTypes in QRscanner.js and uses react-native-camera version 0.7.0 which crashes

testcamera:app:unspecified > testcamera:react-native-camera:unspecified

  • What went wrong:
    A problem occurred configuring project ':app'.

Could not resolve all dependencies for configuration ':app:_debugApkCopy'.
Could not find com.github.react-native-community:cameraview:d529251d24c0a367a28eea28f0eac2269d12f772.
Required by:
testcamera:app:unspecified > testcamera:react-native-camera:unspecified

作者遗漏

请在TitleBar.js中添加import PropTypes from 'prop-types';谢谢

所依赖的react-native-camera为旧版本propType不在支持

该插件所依赖的react-native-camera为0.7.0版本,该版本用到的propType已经在最新的react-native中移除,目前react-native-camera已经升级至0.12.0版本修复了propType这一块,请作者更新下自己的依赖库版本不然其他人使用会报错

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.