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 wheninitState()runs, it kicks off the camera fetch but doesn't wait for it to finish.- The
if(this.cameraGot)check ininitState()will always be false initially—cameraGotonly gets set to true afteravailableCameras()completes. That means yourcontrollernever gets initialized ininitState(). - When the first build happens,
controlleris still null, so trying to accesscontroller.value.aspectRatioorcontroller.value.initializedthrows 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:
Move Controller Initialization to After Camera List is Fetched
Instead of trying to initialize the controller ininitState(), do it right after we get the list of cameras in thegetCamera()method.Add Proper Null & Initialization Checks in Build
Before accessing any properties ofcontroller, 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()inmain(): Required for async operations before launching the app (sinceavailableCameras()is async). - Made
controllernullable (CameraController?) to safely handle its initial null state. - Moved controller initialization and
initialize()call insidegetCamera(), 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
相关产品推荐
相关产品推荐

