世博相机仅使用React Navigation打开一次

时间:2018-06-16 16:14:27

标签: reactjs camera navigation native expo

我将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
    }

});

7 个答案:

答案 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)

要进行此工作,您需要:

  1. import { NavigationEvents } from 'react-navigation';
  2. state = { loaded: true }
  3. 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-> loaded:false),然后再回来(触发onWillFocus并将加载更改为true)。调用render()函数时,它将再次显示<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/

谢谢。