简体   繁体   English

如何一次扫描一个条形码? [反应原生相机]

[英]How to scan one barcode per time? [react-native-camera]

Actually i'm new to React and i'm trying to make a simple barcode scanner which show the scanned barcode in an alert and after pressing "OK" in the alert the user should be able to scan another barcode.实际上我是 React 的新手,我正在尝试制作一个简单的条形码扫描仪,它在警报中显示扫描的条形码,在警报中按“确定”后,用户应该能够扫描另一个条形码。

The issue is that the barcode is continuously scanned and when the alert is up it's hiding and showing every second the alert.问题是条形码被连续扫描,当警报出现时,它会隐藏并每秒显示警报。

I was trying to do something like this to show the alert only once and if OK is pressed to be able to show again the alert but only in case the OK is pressed but that had no effect..我试图做这样的事情来只显示一次警报,如果按下确定能够再次显示警报,但只有在按下确定但没有效果的情况下。

  onBarCodeRead = (e) => {
    if(!this.alertPresent){
      this.alertPresent = true;
          Alert.alert(
            "Barcode type is " + e.type,
            "Barcode value is " + e.data,
            [
                 {text: 'OK', onPress: () => this.alertPresent = false;},
            ],
              {cancelable: false},
          );
      }
  }

Here is full code of Barcode.JS这是 Barcode.JS 的完整代码

import React, { Component } from 'react';
import { Button, Text, View,Alert } from 'react-native';
import { RNCamera } from 'react-native-camera';
import BarcodeMask from 'react-native-barcode-mask';
class ProductScanRNCamera extends Component {

  constructor(props) {
    super(props);
    this.camera = null;
    this.barcodeCodes = [];
    this.alertPresent = false;
    this.state = {
      camera: {
        flashMode: RNCamera.Constants.FlashMode.auto,
      }
    };
  }

  onBarCodeRead = (e) => {
    if(!this.alertPresent){
      this.alertPresent = true;
          Alert.alert(
            "Barcode type is " + e.type,
            "Barcode value is " + e.data,
            [
                 {text: 'OK', onPress: () => this.alertPresent = false;},
            ],
              {cancelable: false},
          );
      }
  }


  pendingView() {
    return (
      <View
      style={{
        flex: 1,
        backgroundColor: 'lightgreen',
        justifyContent: 'center',
        alignItems: 'center',
      }}
      >
      <Text>Waiting</Text>
      </View>
    );
  }

  render() {


    return (
      <View style={styles.container}>
      <RNCamera
      ref={ref => {
        this.camera = ref;
      }}
      defaultTouchToFocus
      flashMode={this.state.camera.flashMode}
      mirrorImage={false}
      onBarCodeRead={this.onBarCodeRead.bind(this)}
      onFocusChanged={() => {}}
      onZoomChanged={() => {}}
      style={styles.preview}
      >
      <BarcodeMask/>
      </RNCamera>
      </View>
    );
  }
}

The trick here is to modify barcodeTypes props with an internal state.这里的技巧是使用内部 state 修改barcodeTypes道具。

const defaultBarcodeTypes = [// should be all Types from RNCamera.Constants.BarCodeType];

class ProductScanRNCamera extends Component {
   state = {
      // your other states
      barcodeType: '',
      barcodeValue: '',
      isBarcodeRead: false // default to false
   }

   onBarcodeRead(event) {
      this.setState({isBarcodeRead: true, barcodeType: event.type, barcodeValue: event.data});
   }

   // run CDU life-cycle hook and check isBarcodeRead state
   // Alert is a side-effect and should be handled as such.
   componentDidUpdate() {
      const {isBarcodeRead, barcodeType, barcodeValue} = this.state;
      if (isBarcodeRead) {
         Alert.alert(barcodeType, barcodeValue, [
           { 
               text: 'OK', 
               onPress: () => {
                   // Reset everything 
                   this.setState({isBarcodeRead: false, barcodeType: '', barcodeValue: ''})
               }
           }
         ]);
      }

   }

   render() {
      const {isBarcodeRead} = this.state;
      return (
         <RNCamera {...your other props} barcodeTypes={isBarcodeRead ? [] : defaultBarcodeTypes}>
            <BarcodeMask />
         </RNCamera>
      )

   }
}

A hook version is cleaner钩子版本更干净

const ProductScanRNCamera = () => {
   const [isBarcodeRead, setIsBarcodeRead] = useState(false);
   const [barcodeType, setBarcodeType] = useState('');
   const [barcodeValue, setBarcodeValue] = useState('');

   useEffect(() => {
      if (isBarcodeRead) {
          Alert.alert(
             barcodeType, 
             barcodeValue, 
             [
                {
                    text: 'OK',
                    onPress: () => {
                        // reset everything
                        setIsBarcodeRead(false);
                        setBarcodeType('');
                        setBarcodeValue('');
                    }
                }
             ]
          );
      }

   }, [isBarcodeRead, barcodeType, barcodeValue]);

   const onBarcodeRead = event => {
      if (!isBarcodeRead) {
         setIsBarcodeRead(true);
         setBarcodeType(event.type);
         setBarcodeValue(event.data);
      }
   }

   return (
      <RNCamera {...your props} 
                onBarCodeRead={onBarcodeRead} 
                barcodeTypes={isBarcodeRead ? [] : defaultBarcodeTypes}>
         <BarcodeMask />
      </RNCamera>
   )
}

use setState in order to set state of component.setState will take the object and update the state of component使用 setState 来设置组件的 state。setState 将采用 object 并更新组件的 state

check code below检查下面的代码

import React, { Component } from 'react';
import { Button, Text, View, Alert } from 'react-native';
import { RNCamera } from 'react-native-camera';
import BarcodeMask from 'react-native-barcode-mask';
class ProductScanRNCamera extends Component {

  constructor(props) {
    super(props);
    this.camera = null;
    this.barcodeCodes = [];
    this.showAlert = true;
    this.state = {
      camera: {
        flashMode: RNCamera.Constants.FlashMode.auto,
      }
    };
  }

  onBarCodeRead = (e) => {
    if (this.state.alertPresent) {
      this.setState({ showAlert: false });
      Alert.alert(
        "Barcode type is " + e.type,
        "Barcode value is " + e.data,
        [
          { text: 'OK', onPress: () =>console.log('ok')  },
        ],
        { cancelable: false },
      );
    }
  }


  pendingView() {
    return (
      <View
        style={{
          flex: 1,
          backgroundColor: 'lightgreen',
          justifyContent: 'center',
          alignItems: 'center',
        }}
      >
        <Text>Waiting</Text>
      </View>
    );
  }

  render() {

    return (
      <View style={styles.container}>
        <RNCamera
          ref={ref => {
            this.camera = ref;
          }}
          defaultTouchToFocus
          flashMode={this.state.camera.flashMode}
          mirrorImage={false}
          onBarCodeRead={this.onBarCodeRead.bind(this)}
          onFocusChanged={() => { }}
          onZoomChanged={() => { }}
          style={styles.preview}
        >
          <BarcodeMask />
        </RNCamera>
      </View>
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM