Flutter FutureBuilder相机已经初始化完成

Flutter FutureBuilder相机已经初始化完成

问题描述

我是Flutter的新手,我想使用FutureBuilder制作一个简单的相机界面。这是我的代码

import 'dart:developer';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';

import 'DisplayImagePage.dart';

class CameraScreen extends StatefulWidget {

  @override
  _CameraScreenState createState() => _CameraScreenState();

}

class _CameraScreenState extends State<CameraScreen> {
  late CameraController _controller;
  late final CameraDescription camera;


  @override
  void initState() {
    super.initState();
  }

  Future<void> prepareCamera() async
   {
    _getCamera().then((CameraDescription camera)
    {
      _controller = CameraController(camera, ResolutionPreset.medium);
      _controller.initialize().then((_) {
        if (!mounted) {
          return;
        }
        setState(() {});
      });
    }
    );
  }

  Future<CameraDescription> _getCamera() async
  {

    final cameras = await availableCameras();
    if (cameras.isEmpty) {
      // No cameras available
      log("Camera is empty!");
    }
    final firstCamera = cameras.first;
    camera = firstCamera;
    return firstCamera;
  }

  Future<String> _takeSelfie(BuildContext context) async {

    final XFile image = await _controller.takePicture();
    var takenImagePath = image.path;

    return takenImagePath;

    }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(
        title: Text('Take a Selfie'),
      ),
      body: FutureBuilder(
        future: prepareCamera(),
        builder: (ctx, snapshot)
        {
          if(snapshot.hasData)
          {
            log(snapshot.toString());
            return AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              child: CameraPreview(_controller),
            );
          }
          else if (snapshot.hasError)
          {
            return Center(
              child: Text(
                '${snapshot.error} occured',
                style: TextStyle(fontSize: 18),
              ),
            );
          }
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          try {
            var path = await _takeSelfie(context);
            Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (context) => DisplayImagePage(imageUrl: path),
                ));
          } catch (e) {
            print(e);
          }
        },
        child: Icon(Icons.camera),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

在我给予相机访问权限之后,我在控制台上看到了以下错误:
“`dart Error: LateInitializationError: Field ‘camera’ has already been initialized. “` 为什么在只调用一次`_getCamera()`的情况下,它还尝试重新赋值相机? 我尝试将`_getCamera()`和`PrepareCamera`函数包装在一起,但这并没有起作用。 解决方案: 每当您的有状态的`StatefulWidget`更新时,将调用`build`方法,所以`FutureBuilder`会在每次`build`时调用`prepareCamera`。为了防止这种情况发生,我建议你将`camera`设为可为空,而不是使用`late`初始化,并将`_getCamera`的逻辑改为以下方式:

class _CameraScreenState extends State<CameraScreen> {
  late CameraController _controller;
  CameraDescription? camera;

  // ...
}
Future<CameraDescription> _getCamera() async
{
  if (camera == null) {
    final cameras = await availableCameras();
    if (cameras.isEmpty) {
      // No cameras available
      log("Camera is empty!");
    }
    final firstCamera = cameras.first;
    camera = firstCamera;
    return firstCamera;
  }

  return camera; // add this too
}

解决方案

每次StatefulWidget的状态更新时,都会调用build方法,因此FutureBuilder将在每次构建时调用preparerecamera。为了防止这种情况发生,我建议你让camera为空而不是使用late初始化,并让_getCamera内部的逻辑像这样:

class _CameraScreenState extends State<CameraScreen> {
  late CameraController _controller;
  CameraDescription? camera;

  // ...
}
Future<CameraDescription> _getCamera() async
{
  if (camera == null) {
    final cameras = await availableCameras();
    if (cameras.isEmpty) {
      // No cameras available
      log("Camera is empty!");
    }
    final firstCamera = cameras.first;
    camera = firstCamera;
    return firstCamera;
  }

  return camera; // add this too
}

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程