ReactNative相机扫码

React Native相机扫码

我最近一直在学习RN,当然中间也遇到了很多问题 ,下面是关于RN扫码的一些坑,觉得还是把这些坑都写出来,方便 RN的初学者。

react-native-camera

首先,进行依赖下载安装

npm install react-native-camera --save

权限配置

  1. 首先找到 android/app/src/main/AndroidManifest.xml 此目录文件,在该文件中添加如下代码
    <uses-permission android:name="android.permission.CAMERA" />

  2. 然后找到 app/build.gradle 此文件,在该文件中添加如下代码
    missingDimensionStrategy 'react-native-camera', 'general' implementation project(path: ':react-native-camera')

    分别是在defaultConfig和dependencies中添加
    defaultConfig{ missingDimensionStrategy 'react-native-camera', 'general' }
    dependencies{ implementation project(path: ':react-native-camera') }

  3. 最后找到 android/settings.gradle 此文件,在该文件中添加
    include ':react-native-camera' project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')

  4. 此时,准备工作已全部完成,可以进行相关业务逻辑代码编写

文件代码

import {RNCamera} from 'react-native-camera';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {StyleSheet, Animated, View, Text, Button, Easing} from 'react-native';
import navigate from '../../utils/NavigateUtil';
import ModalSelect from '../../components/ModalSelect';
import List from '../../components/List';
import {gh} from '../../utils/autoSize';
import Vibrate, {VibratePress} from '../../utils/vibrate';

export default function Camera() {
  const [flash, setFlash] = useState(false);
  const lastScannedDataRef = useRef(null);
  const moveAnim = useRef(new Animated.Value(-2)).current;
  const [showModal, setShowModal] = useState(false);
  const [dataList, setDataList] = useState([]);

  /** 扫描框动画*/
  const startAnimation = () => {
    Animated.sequence([
      Animated.timing(moveAnim, {
        toValue: 200,
        duration: 1500,
        easing: Easing.linear,
        useNativeDriver: false,
      }),
      Animated.timing(moveAnim, {
        toValue: -1,
        duration: 1500,
        easing: Easing.linear,
        useNativeDriver: false,
      }),
    ]).start(() => startAnimation());
  };

  // 开始调用一次
  useEffect(() => {
    startAnimation();
  }, []);

  const onBarCodeRead = useCallback(
    (result: {data: string}) => {
      const {data} = result;
      if (data && data !== lastScannedDataRef.current) {
      
        //此处,可以根据自己的需求修改,当拿到数据后,该执行什么样的逻辑,
        // setShowModal(true);
        // const arr = data.split(',');
        // const obj: any = {};
        // for (let i = 0; i < arr.length; i++) {
        //   obj['field' + (i + 1)] = arr[i];
        // }
        // const dataList = Object.values(obj)
        //   .filter(value => value !== '')
        //   .map(value => ({item: value}));
        // setDataList(dataList);
      }
    },
    [navigate],
  );

  return (
    <>
      <View style={styles.container}>
        <RNCamera
          captureAudio={false}
          autoFocus={RNCamera.Constants.AutoFocus.on} 
          style={[styles.preview]}
          type={RNCamera.Constants.Type.back} 
          flashMode={
            flash
              ? RNCamera.Constants.FlashMode.torch
              : RNCamera.Constants.FlashMode.off
          } 
          onBarCodeRead={onBarCodeRead}
          
          //此处是类型,即相机可以识别的码类型
          barCodeTypes={[
            RNCamera.Constants.BarCodeType.qr,
            RNCamera.Constants.BarCodeType.code128,
            RNCamera.Constants.BarCodeType.code39,
            RNCamera.Constants.BarCodeType.code93,
            RNCamera.Constants.BarCodeType.ean13,
            RNCamera.Constants.BarCodeType.ean8,
            RNCamera.Constants.BarCodeType.pdf417,
            RNCamera.Constants.BarCodeType.upc_e,
            RNCamera.Constants.BarCodeType.interleaved2of5,
            RNCamera.Constants.BarCodeType.itf14,
            RNCamera.Constants.BarCodeType.aztec,
            RNCamera.Constants.BarCodeType.datamatrix,
          ]}>
          <View
            style={{
              width: 500,
              height: 220,
              backgroundColor: 'rgba(0,0,0,0.5)',
            }}
          />

          <View style={[{flexDirection: 'row'}]}>
            <View
              style={{
                backgroundColor: 'rgba(0,0,0,0.5)',
                height: 200,
                width: 200,
              }}
            />
            <View style={{width: 200, height: 200}}>
              <Animated.View
                style={[styles.border, {transform: [{translateY: moveAnim}]}]}
              />
            </View>
            <View
              style={{
                backgroundColor: 'rgba(0,0,0,0.5)',
                height: 200,
                width: 200,
              }}
            />
          </View>

          <View
            style={{
              flex: 1,
              backgroundColor: 'rgba(0, 0, 0, 0.5)',
              width: 500,
              alignItems: 'center',
            }}>
            <Text style={styles.rectangleText}>
              将二维码放入框内,即可自动扫描
            </Text>
            <Button
              onPress={() => {
                setFlash(!flash);
              }}
              title={(flash ? '关闭' : '打开') + '闪光灯'}
            />
          </View>
        </RNCamera>
      </View>

    //此处也可根据需求修改,这里是将拿到的数据以弹框的形式展现出来
      {showModal && (
        <ModalSelect
          cancel={() => {
            Vibrate.btn();
            setShowModal(false);
          }}
          title={'选择'}
          RenderList={() => {
            return (
              <View
                style={{
                  width: '100%',
                  height: '100%',
                  paddingTop: gh(10),
                  paddingBottom: gh(10),
                }}>
                <List
                  data={dataList}
                  titleKey={'item'}
                  onPress={data => {
                    const d = data.item;
                    console.log(d);
                    setShowModal(false);
                    navigate('Manufacturer', {partNumber: d});
                  }}
                  itemAlign="center"
                />
              </View>
            );
          }}
        />
      )}
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
  },
  preview: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  rectangleContainer: {
    flex: 1,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  rectangle: {
    height: 200,
    width: 200,
    borderWidth: 1,
    borderColor: '#fcb602',
    backgroundColor: 'transparent',
    borderRadius: 10,
  },
  rectangleText: {
    flex: 0,
    color: '#fff',
    marginTop: 10,
  },
  border: {
    flex: 0,
    width: 196,
    height: 2,
    backgroundColor: '#fcb602',
    borderRadius: 50,
  },
});

入口文件


<Button title='测试按钮' onPress={async () => {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.CAMERA,
    );
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
    //跳转至扫码组件,即可开始扫码
      navigate('Camera');
    } else {
      console.log('拒绝');
      return;
    }
          }} />

ok,此时扫码功能已正常实现。如果有问题,欢迎评论交流。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小童不学前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值