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

Flutter相机应用报错:getter 'value'被调用在null对象上

Fixing "The getter 'value' was called on null" in Flutter Camera App

Hey there, let's break down why you're running into this error and how to fix it.

The Root Cause

Your CameraController instance is null when the widget first builds. Here's exactly why:

  • getCamera() is an asynchronous method, so when initState() runs, it kicks off the camera fetch but doesn't wait for it to finish.
  • The if(this.cameraGot) check in initState() will always be false initially—cameraGot only gets set to true after availableCameras() completes. That means your controller never gets initialized in initState().
  • When the first build happens, controller is still null, so trying to access controller.value.aspectRatio or controller.value.initialized throws the "getter 'value' called on null" error.

Step-by-Step Fixes

Let's adjust your code to handle async camera setup properly and add safe null checks:

  1. Move Controller Initialization to After Camera List is Fetched
    Instead of trying to initialize the controller in initState(), do it right after we get the list of cameras in the getCamera() method.

  2. Add Proper Null & Initialization Checks in Build
    Before accessing any properties of controller, make sure it's not null and has finished initializing.

Modified Working Code

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

List<CameraDescription> cameras;

void main() async {
  // Critical: Initialize Flutter's binding first for async operations in main
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MaterialApp(
    home: CameraApp(),
  ));
}

class CameraApp extends StatefulWidget {
  const CameraApp({super.key});

  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  CameraController? controller; // Mark as nullable to handle initial null state
  bool cameraGot = false;

  Future<void> getCamera() async {
    final cameras = await availableCameras();
    // Initialize controller immediately after fetching cameras
    controller = CameraController(cameras[0], ResolutionPreset.medium);
    
    // Wait for controller to finish initializing
    await controller!.initialize();
    
    // Guard against state updates on disposed widgets
    if (!mounted) return;
    
    setState(() {
      cameraGot = true;
    });
  }

  @override
  void initState() {
    super.initState();
    getCamera(); // Start camera setup process
  }

  @override
  void dispose() {
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // Show loading state while controller is null or uninitialized
    if (controller == null || !controller!.value.isInitialized) {
      return const Scaffold(
        body: Center(child: CircularProgressIndicator()),
      );
    }

    return Scaffold(
      body: Stack(
        children: <Widget>[
          // Camera preview with correct aspect ratio
          AspectRatio(
            aspectRatio: controller!.value.aspectRatio,
            child: CameraPreview(controller!),
          ),
          // Example overlay widget on top of camera view
          const Positioned(
            top: 40,
            left: 20,
            child: Text(
              "Camera Overlay",
              style: TextStyle(color: Colors.white, fontSize: 20),
            ),
          ),
        ],
      ),
    );
  }
}

Key Changes Explained

  • Added WidgetsFlutterBinding.ensureInitialized() in main(): Required for async operations before launching the app (since availableCameras() is async).
  • Made controller nullable (CameraController?) to safely handle its initial null state.
  • Moved controller initialization and initialize() call inside getCamera(), ensuring we only create the controller after we have the camera list.
  • Added a loading indicator in build() while the controller is setting up, instead of trying to render the camera preview prematurely.
  • Cleaned up unnecessary nested widgets in the camera view to simplify the code.

Additional Tips

  • Always handle async operations carefully in Flutter stateful widgets—never assume an async method has completed when initState() finishes.
  • Use nullable types and null checks to avoid runtime errors like this one.
  • Wrap controller operations in if (!mounted) return; to prevent state updates on a disposed widget.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:34:00