如何一次扫描一个条码? [反应本机相机]
How to scan one barcode per time? [react-native-camera]
实际上我是 React 的新手,我正在尝试制作一个简单的条形码扫描仪,它在警报中显示扫描的条形码,在警报中按 "OK" 后,用户应该能够扫描另一个条形码。
问题是条形码被连续扫描,当警报出现时,它每秒隐藏和显示警报。
我试图做这样的事情来只显示一次警报,如果按下确定可以再次显示警报,但只有在按下确定但没有效果的情况下..
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},
);
}
}
这里是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>
);
}
}
使用 setState 来设置 component.setState 的状态将获取对象并更新组件的状态
检查下面的代码
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>
);
}
}
这里的技巧是用内部状态修改 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>
)
}
}
钩子版本更干净
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>
)
}
实际上我是 React 的新手,我正在尝试制作一个简单的条形码扫描仪,它在警报中显示扫描的条形码,在警报中按 "OK" 后,用户应该能够扫描另一个条形码。
问题是条形码被连续扫描,当警报出现时,它每秒隐藏和显示警报。
我试图做这样的事情来只显示一次警报,如果按下确定可以再次显示警报,但只有在按下确定但没有效果的情况下..
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},
);
}
}
这里是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>
);
}
}
使用 setState 来设置 component.setState 的状态将获取对象并更新组件的状态
检查下面的代码
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>
);
}
}
这里的技巧是用内部状态修改 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>
)
}
}
钩子版本更干净
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>
)
}