【问题标题】:Camera Freeze: How to reinitialise camera component?相机冻结:如何重新初始化相机组件?
【发布时间】:2018-04-14 09:03:22
【问题描述】:

使用相机拍照,然后导航到另一个有后退按钮的页面,在点击事件时我再次导航到相机,但这次相机冻结但我可以点击另一张照片。

如果导航流程是相机 => 其他组件(例如相机点击图片视图)=> 相机,则观察到相机冻结。

如果导航流程是其他组件(例如,除了摄像头之外的任何组件)=> 摄像头,则不会发生摄像头冻结。可能需要杀死相机的东西,然后导航应该发生。

包线程:react-native-camera-kit

【问题讨论】:

    标签: react-native-android react-native-camera


    【解决方案1】:

    我已经解决了这个问题,但在互联网上进行了几次搜索后,我使用componentDidMount解决了它

    React-navigation 在选项卡之间切换时不会卸载组件。因此,当您离开并返回带有相机组件的屏幕时,它将只是黑色视图。所以一个好的解决方案是使用componentDidMount 并添加两个监听器willFocuswillBlur 来帮助您挂载和卸载视图。

    componentDidMount() {
       const { navigation } = this.props;
       navigation.addListener('willFocus', () =>
         this.setState({ focusedScreen: true })
       );
       navigation.addListener('willBlur', () =>
         this.setState({ focusedScreen: false })
       );
     }
    
    
    
    
        render() {
            const { isPermitted, focusedScreen } = this.state;
            if (isPermitted === null) {
              return (<View style={{flex:1, justifyContent:'center',alignItems:'center'}}>
                <Text>Error</Text>
              </View>);
            } else if (isPermitted === false) {
              return (<View style={{flex:1, justifyContent:'center',alignItems:'center'}}>
              <ActivityIndicator size="large" style={{color:'blue', fontSize:30}} />
                <Text>No Acceas to camera</Text>
              </View>);
            } else if (focusedScreen){
              return ( <View>
                <FullPageLoader isVisible={this.state.isLoader} TextToShow={this.state.loaderText} />
                <CameraKitCameraScreen
                actions={{ leftButtonText: <Icon name='close' style={{color:'white',fontSize:30}}/>,rightButtonText: <Icon name='images' style={{color:'white',fontSize:40}}/> }}
                onBottomButtonPressed={event => this.onBottomButtonPressed(event)}
                ref= {(cam) => {
                  this.camera = cam;
                }}
                flashImages={{
                  on: require('./img/flashon.png'),
                  off: require('./img/flashoff.png'),
                  auto: require('./img/flashauto.png'),
                }}
                TopTitle={this.state.title}
                cameraFlipImage={require('./img/flip-camera.png')}
                captureButtonImage={require('./img/capture.png')}
                cameraOptions={{
                  flashMode: 'auto',             // on/off/auto(default)
                  focusMode: 'on',               // off/on(default)
                  zoomMode: 'on',                // off/on(default)
                  ratioOverlayColor: '#00000077'
                }}
                style={{height:'100%'}}
              />
              </View>);
            }else{
              return (<Text>Camera Error</Text>);
            }
          }
    

    参考:https://github.com/react-native-community/react-native-camera/blob/master/docs/react-navigation.md

    【讨论】:

      【解决方案2】:

      对于那些使用 Expo 和 React Native 功能组件的人来说,这变得更加复杂。

      对于那些第一次到达的人来说,问题是 React Native 屏幕不会在离开时破坏相机。您可以创建多个摄像头屏幕,但是当您返回到前一个摄像头屏幕时,预览似乎会冻结,因为该屏幕上的摄像头永远不会重新初始化。

      我的解决方案是创建一个相机,并根据 UI 的需要有条件地切换 UI 渲染组件。

      类似这样的:

      import React, { useEffect, useState } from 'react';
      import { StyleSheet, View, Button } from 'react-native';
      import { Camera } from 'expo-camera';
      import * as Permissions from 'expo-permissions';
      
      export default function App() {
      
         const [hasCameraPermission, setHasCameraPermission] = useState(false);
         const [cameraMode1, setCameraMode1] = useState(true);
      
         const takePicture = async () => {
              if (cameraMode1) {
                 alert("Picture mode 1");
                 setCameraMode1(false);
              } else {
                 alert("Picture mode 2");
                 setCameraMode1(true);
              }
          }
      
          useEffect(() => {
              async function getCameraStatus() {
                  const { status } = await Permissions.askAsync(Permissions.CAMERA);
                  setHasCameraPermission(status == 'granted');
              }
              getCameraStatus();
          }, [hasCameraPermission]);
      
          return (
            <View style={{ flex: 1}}>
              <Camera
                    style={[StyleSheet.absoluteFillObject]}
              />
              {cameraMode1 ?
              <Button
                  title="Camera Mode 1"
                  onPress={() => { takePicture() }}
              />
              :
              <Button
                  title="Camera Mode 2"
                  onPress={() => { takePicture() }}
              />
              }
             </View>
          );
      }
      

      你可以Test out this code on Expo Snack

      【讨论】:

        猜你喜欢
        • 2012-08-05
        • 1970-01-01
        • 1970-01-01
        • 2020-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多