React Native Vision Camera v2.16.2 Android相机界面显示异常求助
React Native Vision Camera v2.16.2 画面偏移及布局异常解决方案
问题现象
使用React Native集成Vision Camera v2.16.2版本(因新版本与当前RN版本不兼容),相机权限请求成功后打开,但界面显示异常:画面偏移出屏幕,圆形拍照按钮跑到屏幕顶部,调整布局后问题仍未解决。
解决方案
1. 调整容器基础布局
移除父容器的justifyContent: 'center'和alignItems: 'center',避免干扰绝对定位元素的布局逻辑,保持容器为全屏flex容器即可。
2. 修正Camera组件适配
为Camera组件添加format属性,选择与屏幕比例匹配的相机格式,避免画面拉伸或偏移。
3. 修复图片路径语法错误
原代码中图片URI的file://'${imageSource}'多了单引号,会导致图片加载失败,需修正为正确的格式。
修改后的完整代码
import React, { useState, useEffect, useRef } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, Image, Linking } from 'react-native'; import { Camera, useCameraDevices } from 'react-native-vision-camera'; function AddPicture() { const [cameraPosition, setCameraPosition] = useState('back') const [showCamera, setShowCamera] = useState(true); const [imageSource, setImageSource] = useState(''); const devices = useCameraDevices()?.[cameraPosition]; const camera = useRef(null); useEffect(() => { async function getPermission() { const newCameraPermission = await Camera.requestCameraPermission(); console.log("permission status: ", newCameraPermission); if (newCameraPermission === 'denied') { await Linking.openSettings(); } }; getPermission(); }, []); const capturePhoto = async () => { if (camera.current !== null) { const photo = await camera.current.takePhoto({ flash:'on' }); setImageSource(photo.path); setShowCamera(false); console.log(photo.path); } }; const handleBack = () => { setShowCamera(true); setImageSource(''); }; if (devices == null) { return <Text>Camera not available</Text>; } // 选择适配屏幕的相机格式 const format = devices.formats.find(f => f.videoWidth / f.videoHeight === 9/16) || devices.formats[0]; return ( <View style={styles.container}> {showCamera ? ( <> <Camera ref={camera} style={StyleSheet.absoluteFill} device={devices} isActive={showCamera} photo={true} format={format} // 添加格式适配 /> <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={handleBack}> <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) setImageSource(''); }}> <Text style={{color: 'white', fontWeight: '500'}}> Use Photo </Text> </TouchableOpacity> </View> </View> </> )} </View> ); } export default AddPicture; const styles = StyleSheet.create({ container: { flex: 1, // 移除居中属性,避免干扰绝对定位元素 }, 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, backgroundColor: '#B2BEB5', alignSelf: 'center', borderWidth: 4, borderColor: 'white', }, image: { width: '100%', height: '100%', aspectRatio: 9 / 16, }, });
额外说明
- 若仍存在画面适配问题,可尝试调整
format的选择逻辑,比如优先选择支持最高分辨率的格式,或者根据设备屏幕尺寸动态计算比例。 - 确保项目中已正确配置Vision Camera的原生依赖,比如iOS的Info.plist权限声明、Android的AndroidManifest.xml权限配置。
内容的提问来源于stack exchange,提问作者jordyng
相关产品推荐
相关产品推荐

