【问题标题】:Initializing camera for list of available cameras in Future为未来可用的相机列表初始化相机
【发布时间】:2022-08-02 16:11:53
【问题描述】:

我正在使用我直接从 pub.dev 获得的关于初始化相机和创建可用相机列表的代码

该列表是在 Future main() 函数中创建的,但是当我导航到 CameraApp 页面时它不会被自动调用。有没有人遇到过这个问题?当使用此代码导航到页面时,如何初始化相机并创建可用相机列表?请帮忙,谢谢。

/// CameraApp is the Main Application.
class CameraApp extends StatelessWidget {
  /// Default Constructor
  const CameraApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CameraExampleHome(),
    );
  }
}

List<CameraDescription> _cameras = <CameraDescription>[];

Future<void> main() async {
  // Fetch the available cameras before initializing the app.
  try {
    WidgetsFlutterBinding.ensureInitialized();
    _cameras = await availableCameras();
  } on CameraException catch (e) {
    _logError(e.code, e.description);
  }
  runApp(const CameraApp());
}

这是我从按钮内部调用 CameraApp 函数的代码:

ElevatedButton(
              onPressed: () 
              {Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => CameraApp()));},
              child: const Text(\'Camera\'),
              style: ElevatedButton.styleFrom(
                  minimumSize: const Size(160.0, 35.0)),

            ),
  • 抱歉,如果我的问题不清楚,我正在尝试初始化和 camera_ 中的相机列表,但是当我调用 CameraApp 函数时,获取列表的 Future main() 函数没有执行。
  • 有人可以帮助我,让我知道相机是否应该始终在 main() 中初始化,我正试图在外面做这件事,这导致了我这个问题。如果可以在 main() 之外进行初始化,那么正确的结构是什么?
  • 仍然希望得到答案,当从 pub.dev 使用示例代码时,它在一个文件中运行良好,但将代码拆分为不同的组件会导致错误。
  • 好的。在 main.js 中使用一些服务文件初始化和存储相机(和控制器)怎么样?那么在CameraApp中,你从这个服务中访问摄像头吗?
  • 您是否尝试在 CameraApp 文件的 initState 中进行初始化程序调用

标签: flutter dart flutter-dependencies


【解决方案1】:

这里需要考虑的事情很少。您所做的实现是正确的,但是您将相机命名为私有变量,将通过添加像 _cameras 的 _ 在单个 dart 文件中访问该变量。只需导入 main.dart 即可删除它,使其在所有类中全局可用

这是完整的代码

main.dart

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

List<CameraDescription> cameras = <CameraDescription>[];
void main() async {
  try {
    WidgetsFlutterBinding.ensureInitialized();
    cameras = await availableCameras();
    print(cameras);
  } on CameraException catch (e) {
    print(e.toString());
  }
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: CameraApp());
  }
}

class CameraApp extends StatelessWidget {
  /// Default Constructor
  const CameraApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CameraExampleHome(),
    );
  }
}

cameraExampleHome.dart

import 'package:flutter/material.dart';

import 'main.dart';

class CameraExampleHome extends StatefulWidget {
  const CameraExampleHome({Key? key}) : super(key: key);

  @override
  State<CameraExampleHome> createState() => _CameraExampleHomeState();
}

class _CameraExampleHomeState extends State<CameraExampleHome> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Available Cameras $cameras"),
//output: Available Cameras [CameraDescription(0, CameraLensDirection.back, 90), CameraDescription(1, CameraLensDirection.front, 270), CameraDescription(2, CameraLensDirection.front, 270)]
      ),
    );
  }
}

【讨论】:

  • 谢谢@KaushikChandru,但是导入主要的编码风格好吗?我总是被教导这是不好的做法
  • 但是您已经在 main.dart 中定义了根级别的摄像机列表。如果您希望将其保留在根级别并且仍然可以在 main.dart 中访问它,您可以将其移动到其他一些 dart 文件中。保存此变量的最佳做法是创建一个单例。但这是一个简单的方法
  • 它是否按预期工作?
【解决方案2】:

您可以为全局变量创建一个库文件。

在您的 lib 文件夹中创建一个名为“globals.dart”的文件。

在顶部声明以下行。

library your_project_name.globals;

然后在其中设置你的变量

List<CameraDescription> cameras = <CameraDescription>[];

主要用途

import 'globals.dart' as globals;

main() {
  ...
  globals.cameras = await availableCameras();
  ...
}

然后只需在项目中的任何位置使用该变量。

import 'globals.dart' as globals;

globals.cameras...

【讨论】:

    【解决方案3】:

    您可以创建一种单例来管理相机操作。

    class CameraManager {
      // Declare your camera list here
      List<CameraDescription> _cameras = <CameraDescription>[];
    
      // Constructor
      CameraManager._privateConstructor() {}
    
      // initialise instance
      static final CameraManager instance =
          CameraManager._privateConstructor();
    
      // Add a getter to access camera list
      bool get cameras => _cameras;
    
      // Init method
      init() async {
        try {
          _cameras = await availableCameras();
        } on CameraException catch (e) {
          _logError(e.code, e.description);
        }
      }
    
      // other needed methods to manage camera
      ...
    }
    

    然后在你的主要功能中

    Future<void> main() async {
      // Fetch the available cameras before initializing the app.
      try {
        WidgetsFlutterBinding.ensureInitialized();
        await CameraManager.instance.init();
      }
      runApp(const CameraApp());
    }
    

    然后在应用程序的其他部分,您可以使用CameraManager.instance. 导入单例并访问方法和属性

    【讨论】:

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