Bird
Raised Fist0
Fluttermobile~20 mins

Camera access in Flutter - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Camera Screen
This screen lets the user open the camera, take a photo, and display the photo on the screen.
Target UI
┌─────────────────────────────┐
│        Camera Screen        │
├─────────────────────────────┤
│                             │
│       [Camera Preview]      │
│                             │
│                             │
│                             │
│                             │
│                             │
│                             │
├─────────────────────────────┤
│  [Take Photo Button]         │
├─────────────────────────────┤
│  [Captured Photo Display]    │
│                             │
│                             │
│                             │
└─────────────────────────────┘
Show live camera preview filling most of the screen
Add a button labeled 'Take Photo' below the preview
When the button is pressed, capture a photo from the camera
Display the captured photo below the button
Handle camera permissions properly
Use Flutter's camera package for implementation
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';

class CameraScreen extends StatefulWidget {
  @override
  State<CameraScreen> createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  CameraController? _controller;
  XFile? _imageFile;

  @override
  void initState() {
    super.initState();
    // TODO: Initialize camera controller here
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Camera Screen')),
      body: Column(
        children: [
          // TODO: Add camera preview widget here
          ElevatedButton(
            onPressed: () {
              // TODO: Add take photo logic here
            },
            child: Text('Take Photo'),
          ),
          // TODO: Show captured photo here
        ],
      ),
    );
  }
}
Task 1
Task 2
Task 3
Task 4
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'dart:io';

class CameraScreen extends StatefulWidget {
  @override
  State<CameraScreen> createState() => _CameraScreenState();
}

class _CameraScreenState extends State<CameraScreen> {
  CameraController? _controller;
  XFile? _imageFile;
  late Future<void> _initializeControllerFuture;

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

  Future<void> _setupCamera() async {
    final cameras = await availableCameras();
    final firstCamera = cameras.first;
    _controller = CameraController(firstCamera, ResolutionPreset.medium);
    _initializeControllerFuture = _controller!.initialize();
    if (mounted) {
      setState(() {});
    }
  }

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

  Future<void> _takePhoto() async {
    try {
      await _initializeControllerFuture;
      final image = await _controller!.takePicture();
      setState(() {
        _imageFile = image;
      });
    } catch (e) {
      print('Error taking photo: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Camera Screen')),
      body: Column(
        children: [
          Expanded(
            flex: 3,
            child: _controller == null
                ? Center(child: CircularProgressIndicator())
                : FutureBuilder<void>(
                    future: _initializeControllerFuture,
                    builder: (context, snapshot) {
                      if (snapshot.connectionState == ConnectionState.done) {
                        return CameraPreview(_controller!);
                      } else {
                        return Center(child: CircularProgressIndicator());
                      }
                    },
                  ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: ElevatedButton(
              onPressed: _controller == null ? null : _takePhoto,
              child: Text('Take Photo'),
            ),
          ),
          Expanded(
            flex: 2,
            child: _imageFile == null
                ? Center(child: Text('No photo taken yet'))
                : Image.file(File(_imageFile!.path)),
          ),
        ],
      ),
    );
  }
}

We start by getting the list of available cameras asynchronously and pick the first one. Then we create a CameraController with medium resolution and initialize it. The CameraPreview widget shows the live camera feed once initialization is done.

The 'Take Photo' button calls _takePhoto() which uses the controller to capture a picture and saves it in _imageFile. We then display the captured photo below the button using Image.file.

We handle loading states with CircularProgressIndicator while the camera initializes. The UI updates reactively when a photo is taken.

This approach follows Flutter's camera package guidelines and ensures a smooth user experience.

Final Result
Completed Screen
┌─────────────────────────────┐
│        Camera Screen        │
├─────────────────────────────┤
│  [Live Camera Preview Here] │
│                             │
│                             │
│                             │
├─────────────────────────────┤
│  [Take Photo Button]         │
├─────────────────────────────┤
│  [Captured Photo Display]    │
│                             │
│                             │
└─────────────────────────────┘
User sees live camera preview filling top area
User taps 'Take Photo' button
App captures photo and displays it below the button
If no photo taken, text 'No photo taken yet' is shown
Stretch Goal
Add a button to switch between front and back cameras.
💡 Hint
Use the list of available cameras and update the CameraController with the selected camera index.

Practice

(1/5)
1. What is the main purpose of the camera package in Flutter?
easy
A. To manage app navigation between screens
B. To access and control the device camera for taking pictures or videos
C. To play audio files in the app
D. To handle user authentication

Solution

  1. Step 1: Understand the package purpose

    The camera package is designed to access device cameras.
  2. Step 2: Match purpose with options

    Only To access and control the device camera for taking pictures or videos describes camera control for pictures or videos.
  3. Final Answer:

    To access and control the device camera for taking pictures or videos -> Option B
  4. Quick Check:

    camera package = device camera access [OK]
Hint: Remember camera package controls device cameras only [OK]
Common Mistakes:
  • Confusing camera package with audio or navigation packages
  • Thinking it handles user login or authentication
  • Assuming it manages app UI layout
2. Which of the following is the correct way to initialize a CameraController in Flutter?
easy
A. CameraController controller = CameraController(camera, ResolutionPreset.high);
B. CameraController controller = new CameraController();
C. CameraController controller = CameraController();
D. CameraController controller = CameraController(camera);

Solution

  1. Step 1: Check CameraController constructor requirements

    The constructor requires a CameraDescription and a ResolutionPreset.
  2. Step 2: Compare options with correct syntax

    CameraController controller = CameraController(camera, ResolutionPreset.high); correctly passes both parameters.
  3. Final Answer:

    CameraController controller = CameraController(camera, ResolutionPreset.high); -> Option A
  4. Quick Check:

    Controller needs camera and resolution [OK]
Hint: Always pass camera and resolution to CameraController [OK]
Common Mistakes:
  • Omitting resolution preset parameter
  • Using empty constructor without parameters
  • Forgetting to import camera package
3. Given this Flutter code snippet, what will be the output on the screen?
final cameras = await availableCameras();
final controller = CameraController(cameras[0], ResolutionPreset.medium);
await controller.initialize();
return CameraPreview(controller);
medium
A. A static image from the camera
B. A blank screen with no camera preview
C. A live camera preview from the first available camera
D. An error because controller is not initialized

Solution

  1. Step 1: Analyze camera initialization

    The code gets available cameras, creates a controller for the first camera, and initializes it.
  2. Step 2: Understand CameraPreview behavior

    After initialization, CameraPreview shows live feed from the camera controller.
  3. Final Answer:

    A live camera preview from the first available camera -> Option C
  4. Quick Check:

    Initialized controller + CameraPreview = live feed [OK]
Hint: Initialized controller + CameraPreview shows live feed [OK]
Common Mistakes:
  • Assuming preview shows static image
  • Forgetting to await controller.initialize()
  • Thinking preview shows blank without error
4. What is wrong with this Flutter code snippet for camera usage?
final cameras = await availableCameras();
final controller = CameraController(cameras[0], ResolutionPreset.high);
return CameraPreview(controller);
medium
A. The controller is not initialized before use
B. The camera list is empty
C. ResolutionPreset.high is invalid
D. CameraPreview requires a widget key

Solution

  1. Step 1: Check controller initialization

    The code creates the controller but does not call initialize() or await it.
  2. Step 2: Understand CameraPreview requirements

    CameraPreview needs an initialized controller to display the camera feed properly.
  3. Final Answer:

    The controller is not initialized before use -> Option A
  4. Quick Check:

    Controller must be initialized before preview [OK]
Hint: Always await controller.initialize() before CameraPreview [OK]
Common Mistakes:
  • Skipping controller.initialize() call
  • Assuming CameraPreview works without initialization
  • Confusing resolution presets with initialization
5. You want to build a Flutter app that takes a picture when a button is pressed and saves it to a file. Which sequence of steps is correct?
hard
A. Call takePicture() before initializing CameraController, then save file
B. Save file first, then initialize CameraController and call takePicture()
C. Show CameraPreview without initializing controller, then call takePicture()
D. Initialize CameraController, show CameraPreview, call takePicture(), save file

Solution

  1. Step 1: Initialize and prepare camera

    First, create and initialize the CameraController to access the camera hardware.
  2. Step 2: Show live preview and take picture

    Display CameraPreview so user sees camera feed, then call takePicture() on button press.
  3. Step 3: Save the captured image file

    After taking picture, save the returned file to storage.
  4. Final Answer:

    Initialize CameraController, show CameraPreview, call takePicture(), save file -> Option D
  5. Quick Check:

    Init controller -> preview -> takePicture -> save [OK]
Hint: Initialize first, preview, then take and save picture [OK]
Common Mistakes:
  • Calling takePicture before initialization
  • Skipping preview and confusing flow
  • Trying to save before taking picture
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard