You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Flutter异步函数中相机控制器初始化延迟瞬间报错问题

解决Flutter Web相机页面LateInitializationError红屏问题

问题原因

你遇到的LateInitializationError是因为页面首次构建时,camController还没完成异步初始化(getCamera是异步方法,initState调用后不会等待它执行完毕就开始build),但你直接在build方法里访问了camController.value,触发了未初始化错误,导致红屏闪烁。

修复方案

核心思路是在build阶段先判断camController是否已经被实例化,再检查其初始化状态。这里提供两种可行的修改方式:

方式1:使用可空类型替代late修饰符

将camController改为可空类型,初始值设为null,在build里先判断控制器是否存在,再检查初始化状态:

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

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

  @override
  State<CreateView> createState() => _CreateViewState();
}

class _CreateViewState extends State<CreateView> {
  List<CameraDescription>? deviceCameras;
  CameraController? camController; // 改为可空类型

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

  void getCamera() async {
    final cameras = await availableCameras();
    final controller = CameraController(cameras.first, ResolutionPreset.high, enableAudio: false);
    await controller.initialize().then((value) {
      if (!mounted) {
        return;
      }
      setState(() {
        camController = controller;
      });
    }).catchError((e) {
      print(e);
    });
  }

  @override
  void dispose() {
    camController?.dispose(); // 使用空安全调用
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // 先判断控制器是否已实例化,再检查初始化状态
    if (camController != null && camController!.value.isInitialized) {
      return Scaffold(
        body: Center(
          child: SingleChildScrollView(
            child: Container(
              padding: const EdgeInsets.all(20),
              decoration: BoxDecoration(
                color: const Color.fromARGB(136, 255, 255, 255),
                borderRadius: const BorderRadius.all(Radius.circular(20)),
                boxShadow: [
                  BoxShadow(
                      color: const Color.fromARGB(37, 0, 0, 0),
                      spreadRadius: 1,
                      blurRadius: 15)
                ],
              ),
              width: 300,
              child: CameraPreview(camController!),
            ),
          ),
        ),
      );
    } else {
      return const Center(child: CircularProgressIndicator()); // 让加载指示器居中显示
    }
  }
}

方式2:保留late修饰符,添加初始化状态标记

如果不想改动变量类型,可以添加一个布尔变量跟踪控制器是否已被初始化,在build里先判断这个标记:

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

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

  @override
  State<CreateView> createState() => _CreateViewState();
}

class _CreateViewState extends State<CreateView> {
  late List<CameraDescription> deviceCameras;
  late CameraController camController;
  bool _isControllerInitialized = false; // 添加状态标记

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

  void getCamera() async {
    deviceCameras = await availableCameras();
    camController = CameraController(deviceCameras.first, ResolutionPreset.high, enableAudio: false);
    await camController.initialize().then((value) {
      if (!mounted) {
        return;
      }
      setState(() {
        _isControllerInitialized = true;
      });
    }).catchError((e) {
      print(e);
    });
  }

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

  @override
  Widget build(BuildContext context) {
    // 先判断标记,再访问控制器状态
    if (_isControllerInitialized && camController.value.isInitialized) {
      return Scaffold(
        body: Center(
          child: SingleChildScrollView(
            child: Container(
              padding: const EdgeInsets.all(20),
              decoration: BoxDecoration(
                color: const Color.fromARGB(136, 255, 255, 255),
                borderRadius: const BorderRadius.all(Radius.circular(20)),
                boxShadow: [
                  BoxShadow(
                      color: const Color.fromARGB(37, 0, 0, 0),
                      spreadRadius: 1,
                      blurRadius: 15)
                ],
              ),
              width: 300,
              child: CameraPreview(camController),
            ),
          ),
        ),
      );
    } else {
      return const Center(child: CircularProgressIndicator());
    }
  }
}

额外优化点

  • 遵循Dart命名规范,将createView改为CreateView
  • 在dispose方法中使用空安全调用(方式1),避免控制器为null时调用dispose崩溃
  • 把CircularProgressIndicator包裹在Center里,提升加载状态的视觉体验

内容的提问来源于stack exchange,提问作者Dingo99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:40:18