expo运行环境 https://docs.expo.dev
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, Button, StyleSheet } from 'react-native';
import { Camera } from 'expo-camera';
import { useIsFocused } from '@react-navigation/native';
export default function QRCodeScannerScreen() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [barcodeData, setBarcodeData] = useState('');
const isFocused = useIsFocused();
const cameraRef = useRef(null);
useEffect(() => {
// 当进入该屏幕且相机引用存在时,恢复相机预览并将扫描状态设置为未扫描
if (isFocused && cameraRef.current) {
cameraRef.current.resumePreview();
setScanned(false);
}
return () => {
// 当离开该屏幕时,暂停相机预览
if (cameraRef.current) {
cameraRef.current.pausePreview();
}
};
}, [isFocused]);
const onScanPress = async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
if (status === 'granted' && cameraRef.current) {
cameraRef.current.resumePreview();
setScanned(false);
}
};
const onBarCodeScanned = ({ data }) => {
// 当扫描到条码时,将条码数据保存,并将扫描状态设置为已扫描
setBarcodeData(data);
setScanned(true);
if (cameraRef.current) {
cameraRef.current.pausePreview();
}
};
const onCameraReady = () => {
// 相机准备就绪时,将扫描状态设置为未扫描
setScanned(false);
};
const onExitPress = () => {
// 当点击退出按钮时,将扫描状态设置为未扫描,并恢复相机预览
setScanned(false);
if (cameraRef.current) {
cameraRef.current.resumePreview();
}
setHasPermission(null); // 重置相机权限状态,下次进入时重新请求权限
};
return (
<View style={{ flex: 1 }}>
{scanned ? (
<View style={styles.barcodeContainer}>
<Text style={styles.barcodeText}>{barcodeData}</Text>
</View>
) : (!hasPermission || !isFocused) ? (
<Button title="扫描二维码" onPress={onScanPress} />
) : (
<View style={styles.cameraContainer}>
<Camera
style={styles.cameraPreview}
type={Camera.Constants.Type.back}
ref={cameraRef}
onBarCodeScanned={onBarCodeScanned}
onCameraReady={onCameraReady}
/>
<View style={styles.buttonContainer}>
<Button title="退出" onPress={onExitPress} />
</View>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
cameraContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
cameraPreview: {
width: 250,
height: 250,
},
buttonContainer: {
alignItems: 'center',
marginBottom: 20,
},
barcodeContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
barcodeText: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 20,
},
});
网友评论