我希望你一切都好。我在 React Native 应用程序中面临一个与相机集成相关的特殊问题。这是我面临的问题的详细解释:
问题描述: 我正在使用 React Native 构建一个视频录制应用程序,用户可以在前置摄像头和后置摄像头之间切换。但是,我遇到了一个问题,即在某些情况下相机无法在屏幕上正确显示。
以下是问题的具体情况:
2.Key方法:我尝试过使用key属性强制重新渲染相机组件,但并没有完全解决问题。
附加信息:
react-native-vision-camera
进行相机集成。{ "@react-native-camera-roll/camera-roll": "^6.0.0", "react": "18.2.0", "react-native": "0.72.6", "react-native-vector-icons": "^10.0.0", "react-native-video": "^5.2.1", "react-native-vision-camera": "^3.6.4" }
相关代码:
import React, { useState, useEffect, useRef } from 'react';
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { Camera, useCameraDevice } from 'react-native-vision-camera';
import Icon from 'react-native-vector-icons/Ionicons';
function App() {
const [isLoading, setIsLoading] = useState(true);
const [isRecording, setIsRecording] = useState(false);
// ... (other state variables and functions)
useEffect(() => {
async function getPermissions() {
// Request camera and microphone permissions
const cameraPermission = await Camera.requestCameraPermission();
const microphonePermission = await Camera.requestMicrophonePermission();
// Handle permissions and loading state
}
getPermissions();
}, []);
const device = useCameraDevice(/* specify front or back camera */);
const camera = useRef(null);
return (
<View style={{ flex: 1 }}>
{/* Camera component */}
<Camera style={StyleSheet.absoluteFill} ref={camera} device={device} isActive={true} video={true} audio={true} videoQuality="1080p" />
{/* UI elements */}
{isRecording ? /* Show recording timer */ : null}
{!isFrontCamera && !isRecording ? /* Toggle flash button */ : null}
{/* Other UI elements and functionalities */}
</View>
);
}
export default App;
此代码对我有用,请尝试使用此示例
import React, {useEffect, useState, useRef} from 'react';
import {
View,
StyleSheet,
Button,
TouchableOpacity,
Text,
Linking,
Image,
} from 'react-native';
import {Camera, useCameraDevices} from 'react-native-vision-camera';
function App() {
const camera = useRef(null);
const devices = useCameraDevices();
const device = devices.back;
const [showCamera, setShowCamera] = useState(false);
const [imageSource, setImageSource] = useState('');
useEffect(() => {
async function getPermission() {
const newCameraPermission = await Camera.requestCameraPermission();
console.log(newCameraPermission);
}
getPermission();
}, []);
const capturePhoto = async () => {
if (camera.current !== null) {
const photo = await camera.current.takePhoto({});
setImageSource(photo.path);
setShowCamera(false);
console.log(photo.path);
}
};
if (device == null) {
return <Text>Camera not available</Text>;
}
return (
<View style={styles.container}>
{showCamera ? (
<>
<Camera
ref={camera}
style={StyleSheet.absoluteFill}
device={device}
isActive={showCamera}
photo={true}
/>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.camButton}
onPress={() => capturePhoto()}
/>
</View>
</>
) : (
<>
{imageSource !== '' ? (
<Image
style={styles.image}
source={{
uri: `file://'${imageSource}`,
}}
/>
) : null}
<View style={styles.backButton}>
<TouchableOpacity
style={{
backgroundColor: 'rgba(0,0,0,0.2)',
padding: 10,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
borderWidth: 2,
borderColor: '#fff',
width: 100,
}}
onPress={() => setShowCamera(true)}>
<Text style={{color: 'white', fontWeight: '500'}}>Back</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonContainer}>
<View style={styles.buttons}>
<TouchableOpacity
style={{
backgroundColor: '#fff',
padding: 10,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
borderWidth: 2,
borderColor: '#77c3ec',
}}
onPress={() => setShowCamera(true)}>
<Text style={{color: '#77c3ec', fontWeight: '500'}}>
Retake
</Text>
</TouchableOpacity>
<TouchableOpacity
style={{
backgroundColor: '#77c3ec',
padding: 10,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
borderWidth: 2,
borderColor: 'white',
}}
onPress={() => setShowCamera(true)}>
<Text style={{color: 'white', fontWeight: '500'}}>
Use Photo
</Text>
</TouchableOpacity>
</View>
</View>
</>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
button: {
backgroundColor: 'gray',
},
backButton: {
backgroundColor: 'rgba(0,0,0,0.0)',
position: 'absolute',
justifyContent: 'center',
width: '100%',
top: 0,
padding: 20,
},
buttonContainer: {
backgroundColor: 'rgba(0,0,0,0.2)',
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
bottom: 0,
padding: 20,
},
buttons: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '100%',
},
camButton: {
height: 80,
width: 80,
borderRadius: 40,
//ADD backgroundColor COLOR GREY
backgroundColor: '#B2BEB5',
alignSelf: 'center',
borderWidth: 4,
borderColor: 'white',
},
image: {
width: '100%',
height: '100%',
aspectRatio: 9 / 16,
},
});
导出默认应用程序;