[英]React native QR scanner to webview
我將我的應用程序從 expo 轉換為裸反應本機。 我有一個條形碼/QR 掃描儀,它與 expo 模塊“Expo-bar-code-scanner”配合使用效果很好修理。 預期的是掃描包含 URL 的二維碼並在 webview 中打開它。然而,由於轉換是 webview 無法打開並且我的疊加層無法顯示,所以發生了什么。
請幫忙...謝謝:)
下面是我的 QRscreen.js。 網址省略
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button, Modal, TouchableHighlight, Image } from 'react-native';
import { WebView } from 'react-native-webview';
import QRCodeScanner from 'react-native-qrcode-scanner';
import { RNCamera } from 'react-native-camera';
export default function App(){
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(true);
const [modalVisible, setModalVisible] = useState(true);
const [uri, setUri] = useState('omitted');
useEffect(() => {
(async () => {
const { status } = await QRCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
setModalVisible(true);
// console.warn("Scan returned " + data);
setUri({ uri: data })
};
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: 'column'
}}>
<Modal
animationType="slide"
transparent={false}
visible={modalVisible}
onRequestClose={() => {
setScanned(false);
}}>
<View style={{ flex: 1 }}>
<WebView
style={{ flex: 1 }}
source={{uri: uri['uri']}}
/>
<TouchableHighlight
style={{
backgroundColor:'black',
padding: 15,
alignItems: 'center'
}}
onPress={() => {
setModalVisible(!modalVisible);
setScanned(false);
}}
underlayColor='slategray'
>
<Text style={{ color:'white', fontSize: 15 }}>Re Scan</Text>
</TouchableHighlight>
</View>
</Modal>
<QRCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{ marginBottom: 100 }}>
<View style={{ alignItems: 'center', marginBottom: 5 }}>
<Image
style={{
width: 100,
height: 100,
resizeMode: 'contain',
marginBottom: 20,
}}
source={{ uri: 'omitted' }}
/>
<Text style={{ color: 'white', fontSize: 20, fontWeight: 'bold', paddingBottom: 10}}>
QR Code Reader
</Text>
</View>
<View
style={{
borderColor: 'white',
borderTopWidth: 5,
borderBottomWidth: 5,
borderLeftWidth: 1,
borderRightWidth: 1,
paddingVertical: 80,
paddingHorizontal: 100,
}}
/>
<View style={{ alignItems: 'center', marginTop: 5 }}>
<Text style={{ color: 'white', fontSize: 15}}>
QR Scan...
</Text>
</View>
</View>
</QRCodeScanner>
</View>
);
}
您設置的 Uri state 不正確,因為 setUri 是通過推理提供的字符串,作為“省略”提供,所以它怎么會接受{}
。
所以改變
setUri({ uri: 數據 })
到
設置Uri(數據)
假設您確認數據是一個字符串。 在設置為setUri
之前通過記錄它來檢查這一點。
還有改變
來源={{uri: uri['uri']}}
和
來源={{uri}}
因為 uri 顯然不是數組。
您正在使用來自react-native-webview
package 的 WebView 組件來顯示掃描的 URL,但似乎uri prop
沒有正確傳遞給 WebView。您正在為包含 8827437401188 的uri: data
設置 8827437401188 單個屬性 2898 uri: data
,但是在你的 WebView 組件中,你試圖訪問 uri object 的 uri 屬性,所以它應該是source={{uri: uri.uri}}
而不是source={{uri: uri['uri']}}
。
您在handleBarCodeScanned
function 中使用setModalVisible(true)
,但似乎您只想在成功掃描 QR 碼時顯示模式,因此您應該只在掃描為 false 時才將模式設置為可見。
您還應確保 WebView 僅在掃描 URL 時呈現,否則應用程序會在嘗試打開空的 URL 時崩潰。
以下是如何修改代碼以解決這些問題的示例:
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
setUri({ uri: data });
if (!scanned) {
setModalVisible(true);
}
};
...
return (
<View style={{ flex: 1, flexDirection: 'column' }}>
<Modal
animationType="slide"
transparent={false}
visible={modalVisible}
onRequestClose={() => {
setScanned(false);
}}
>
<View style={{ flex: 1 }}>
{uri.uri && <WebView style={{ flex: 1 }} source={{ uri: uri.uri }} />}
<TouchableHighlight
style={{
backgroundColor: 'black',
padding: 15,
alignItems: 'center',
}}
onPress={() => {
setModalVisible(false);
setScanned(false);
}}
>
<Text style={styles.buttonText}>Re Scan</Text>
</TouchableHighlight>
</View>
</Modal>
<QRCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}
>
<View style={{ marginBottom: 100 }}>
<View style={{ alignItems: 'center', marginBottom: 5 }}>
<Image
style={{
width: 100,
height: 100,
resizeMode: 'contain',
marginBottom: 20,
}}
source={{ uri: 'omitted' }}
/>
<Text style={{ color: 'white', fontSize: 20, fontWeight: 'bold', paddingBottom: 10 }}>
QR Code Reader
</Text>
</View>
<View
style={{
borderColor: 'white',
borderTopWidth: 5,
borderBottomWidth: 5,
borderLeftWidth: 1,
borderRightWidth: 1,
paddingVertical: 80,
paddingHorizontal: 100,
}}
/>
<View style={{ alignItems: 'center' }}>
<Text style={styles.centerText}>
<Text style={styles.textBold}>Scan a QR code</Text> to see the result
</Text>
</View>
</View>
</QRCodeScanner>
</View>
);
這里還有一個樣式表:
const styles = StyleSheet.create({
centerText: {
flex: 1,
fontSize: 18,
padding: 32,
color: '#777',
},
textBold: {
fontWeight: '500',
color: '#000',
},
buttonText: {
fontSize: 21,
color: 'rgb(0,122,255)',
},
buttonTouchable: {
padding: 16,
},
});
那是我的二維碼掃描儀出現了,它能夠掃描二維碼。 另外,我不確定是否有必要,但這是我的package.json
如下:
{
"name": "my_qrscan_app",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "react-native start",
"android": "react-native run-android",
"ios": "react-native run-ios",
"web": "expo start --web",
"eject": "react-native eject"
},
"dependencies": {
"@react-native-community/masked-view": "^1.2.4",
"@react-navigation/native": "^5.5.1",
"@react-navigation/stack": "^5.5.1",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "^0.66.0",
"react-native-gesture-handler": "^1.7.0",
"react-native-qrcode-scanner": "^1.1.4",
"react-native-reanimated": "^1.13.0",
"react-native-web": "^0.13.12",
"react-native-webview": "^10.8.0",
"react-navigation": "^4.0.10"
},
不是預期的 output 的原因是使用onBarCodeScanned方法來偵聽掃描成功的事件,但根據要求我可以看到你正在掃描QRCode而不是BarCode 。
使用以下示例嘗試一下:
import React, {useState, useEffect, useRef} from 'react';
import {
Text,
View,
StyleSheet,
Button,
Modal,
TouchableHighlight,
Image,
} from 'react-native';
import {WebView} from 'react-native-webview';
import QRCodeScanner from 'react-native-qrcode-scanner';
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [modalVisible, setModalVisible] = useState(true);
const [uri, setUri] = useState('omitted');
// useEffect(() => {
// (async () => {
// const {status} = await QRCodeScanner?.requestPermissionsAsync();
// setHasPermission(status === 'granted');
// })();
// }, []);
const handleBarCodeScanned = ({type, data}) => {
ref.current?._setScanning(true);
setModalVisible(true);
// console.warn("Scan returned " + data);
setUri({uri: data});
};
const ref = useRef();
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: 'column',
}}>
<Modal animationType="slide" transparent={false} visible={modalVisible}>
<View style={{flex: 1}}>
<WebView style={{flex: 1}} source={{uri: uri.uri}} />
<TouchableHighlight
style={{
backgroundColor: 'black',
padding: 15,
alignItems: 'center',
}}
onPress={() => {
// ref.current?._setScanning(true);
ref.current?._setScanning(false);
setModalVisible(!modalVisible);
}}
underlayColor="slategray">
<Text style={{color: 'white', fontSize: 15}}>Re Scan</Text>
</TouchableHighlight>
</View>
</Modal>
<QRCodeScanner
// onBarCodeScanned={handleBarCodeScanned}
onRead={handleBarCodeScanned}
ref={ref}
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{marginBottom: 100}}>
<View style={{alignItems: 'center', marginBottom: 5}}>
<Image
style={{
width: 100,
height: 100,
resizeMode: 'contain',
marginBottom: 20,
}}
source={{uri: 'omitted'}}
/>
<Text
style={{
color: 'white',
fontSize: 20,
fontWeight: 'bold',
paddingBottom: 10,
}}>
QR Code Reader
</Text>
</View>
<View
style={{
borderColor: 'white',
borderTopWidth: 5,
borderBottomWidth: 5,
borderLeftWidth: 1,
borderRightWidth: 1,
paddingVertical: 80,
paddingHorizontal: 100,
}}
/>
<View style={{alignItems: 'center', marginTop: 5}}>
<Text style={{color: 'white', fontSize: 15}}>QR Scan...</Text>
</View>
</View>
</QRCodeScanner>
</View>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.