我将Expo摄像机设置为在中间选项卡上打开并进行反应导航。但是,只有在我第一次单击该选项卡时才会打开相机。如果我关闭它并返回它只是一个黑屏。此外,拍照按钮不存在。 (我是新的反应原生和有点编码整体)
'use strict';
import React, { Component } from 'react';
import { createBottomTabNavigator } from 'react-navigation';
import { Camera, Permissions } from 'expo';
import {
AppRegistry,
Dimensions,
StyleSheet,
Text,
TouchableOpacity,
View,
Button
} from 'react-native';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
}
class CameraView extends React.Component {
state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
};
async componentWillMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === 'granted' });
}
render() {
const { hasCameraPermission } = this.state;
if (hasCameraPermission === null) {
return <View />;
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
} else {
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={this.state.type}>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
this.setState({
type: this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
});
}}>
<Text
style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>
{' '}Flip{' '}
</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
}
export default createBottomTabNavigator({
Home: HomeScreen,
Camera:CameraView,
Settings: SettingsScreen
});
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
top: 250
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
padding: 15,
paddingHorizontal: 20,
alignSelf: 'center',
margin: 20
}
});
答案 0 :(得分:4)
使用React Navigation 5.x
import { useIsFocused } from '@react-navigation/native';
export const CameraView = (props) => {
const isFocused = useIsFocused();
return (
<View>
{ isFocused && <RNCamera /> }
</View>
)
}
答案 1 :(得分:1)
我遇到了一些问题。
此代码为我解决了此问题:
import { withNavigationFocus } from 'react-navigation'
render() {
const { isFocused } = this.props
return (
<View>
{ isFocused && <RNCamera ... /> }
</View
)
}
export default withNavigationFocus(Camera)
答案 2 :(得分:1)
我通过使用NavigationEvents确定选项卡是否在焦点上并从那里安装和卸载相机来使其工作。如果您需要在其他屏幕上使用相机,这也会释放相机。这是我在您的示例中所做的:
import { NavigationEvents } from 'react-navigation';
...
class CameraView extends React.Component {
constructor(props) {
super(props)
this.state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
isFocused:true
};
}
...
render(){
//...your existing if's
} if(this.state.isFocused === false){
return (
<NavigationEvents
onWillFocus={payload => {
//console.log("will focus", payload);
this.setState({isFocused:true})
}}
onDidBlur={payload => {
//console.log('did leave',payload)
this.setState({isFocused:false})
}}
/>
)
}
} else {
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={this.state.type}>
<NavigationEvents
onWillFocus={payload => {
//console.log("will focus", payload);
this.setState({isFocused:true})
}}
onDidBlur={payload => {
//console.log('did leave',payload)
this.setState({isFocused:false})
}}
/>
//...the rest of your camera code
}
我希望它也对您有用
答案 3 :(得分:1)
我使用useIsFocused
中的钩子react-navigation/native
解决了这个问题。我在Android,iOS和Web上进行了测试
import { useIsFocused } from '@react-navigation/native';
...
const isFocused = useIsFocused();
...
return (
isFocused && (
<Camera
ref={(ref) => {
camera = ref;
}}
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
)
);
答案 4 :(得分:0)
要进行此工作,您需要:
import { NavigationEvents } from 'react-navigation';
state = { loaded: true }
render() {
const { loaded } = this.state;
return (
<View style={styles.container}>
<NavigationEvents
onWillFocus={payload => this.setState({loaded: true})}
onDidBlur={payload => this.setState({loaded: false})}/>
<View style={styles.cameraArea}>
{loaded && (
<Camera
type={Camera.Constants.Type.back}
ref={ref => {
this.camera = ref;
}}
/>
)}
想法是隐藏此摄像机视图(onDidBlur-> loaded:false),然后再回来(触发onWillFocus并将加载更改为true)。调用render()函数时,它将再次显示
</View>
<Camera />
。
如果您有任何问题随时问。
答案 5 :(得分:0)
如果您将RN Expo与React Navigation-Tab Navigator一起使用。
然后只使用unmountOnBlur
-unmountOnBlur Documentation
这将迫使相机在每次导航焦点更改时卸下相机。
答案 6 :(得分:0)
这对我有用。 (导航5.x) 如果您使用的是CAMERA的其他屏幕,则在移动到另一个屏幕时可以轻松卸载该屏幕。
此行为的原因:任何位置只能激活一个摄像机预览 给定时间。如果您的应用中有多个屏幕,则应 只要屏幕未对准焦点,就卸下相机组件。
<Stack.Screen name="camera" component={CameraScreen} options={{unmountOnBlur: true}}/>
</Stack.Navigator>
文档链接:https://docs.expo.io/versions/latest/sdk/camera/
谢谢。