Expo Camera 仅使用 React Navigation 打开一次
Posted
技术标签:
【中文标题】Expo Camera 仅使用 React Navigation 打开一次【英文标题】:Expo Camera only opening once with React Navigation 【发布时间】:2018-11-26 03:00:30 【问题描述】:我将 Expo 相机设置为在带有反应导航的中间选项卡上打开。但是,仅当我第一次单击该选项卡时,相机才会打开。如果我关闭它并返回它只是一个黑屏。拍照按钮也没有。 (作为一个整体,我是 React Native 和有点编码的新手)
'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
);
【问题讨论】:
【参考方案1】:使用反应导航 5.x
import useIsFocused from '@react-navigation/native';
export const CameraView = (props) =>
const isFocused = useIsFocused();
return (
<View>
isFocused && <RNCamera />
</View>
)
useIsFocused Documentation
【讨论】:
谢谢,它成功了。可以是“已接受的答案”【参考方案2】:我遇到了一些问题。
这段代码为我解决了这个问题:
import withNavigationFocus from 'react-navigation'
render()
const isFocused = this.props
return (
<View>
isFocused && <RNCamera ... />
</View
)
export default withNavigationFocus(Camera)
【讨论】:
【参考方案3】:要完成这项工作,您需要:
1.
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;
/>
)
</View>
这个想法是隐藏这个相机视图(onDidBlur->加载:false),然后当你回来时(onWillFocus被触发并将加载更改为true)。当调用 render() 函数时,它将再次显示<Camera />
。
如果您有任何问题,请随时提出。
【讨论】:
【参考方案4】:我通过使用 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
我希望它也适合你
【讨论】:
【参考方案5】:我使用来自react-navigation/native
的钩子useIsFocused
解决了它。我在 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
/>
)
);
【讨论】:
我试图在我的应用程序中加入相同的方法,但是,我收到了一个错误,Couldn't find a navigation object. Is your component inside a screen in a navigator
。任何想法有什么问题以及如何解决这个问题?【参考方案6】:
这对我有用。 (导航 5.x) 如果您为 CAMERA 使用不同的屏幕,您可以在移动到另一个屏幕时轻松卸下屏幕。
此行为的原因:任何时候都只能激活一个相机预览 给定的时间。如果你的应用中有多个屏幕,你应该 每当屏幕失焦时卸载相机组件。
<Stack.Screen name="camera" component=CameraScreen options=unmountOnBlur: true/>
</Stack.Navigator>
文档链接:https://docs.expo.io/versions/latest/sdk/camera/
谢谢。
【讨论】:
这是最简单的修复方法,而且效果很好!【参考方案7】:如果您将 RN Expo 与 React Navigation - Tab Navigator 结合使用。
然后只需使用unmountOnBlur
- unmountOnBlur Documentation
这将强制相机在每次导航焦点更改时卸载。
【讨论】:
以上是关于Expo Camera 仅使用 React Navigation 打开一次的主要内容,如果未能解决你的问题,请参考以下文章
延迟使用 React Native Camera / Expo Camera 捕获图像,设置“处理消息”?
React Native - 从 expo-camera 获取帧
React Native开发之expo中camera的基本使用
Expo XDE React-Native CAMERA_ROLL 权限“未确定”