Switching camera’s in Flutter
Tags: camera, flutter
Published: 2022-03-31 09:32:09

---
title: Switching camera’s in Flutter
published: true
date: 2022-03-06 15:55:38 UTC
tags: Camera,Flutter
canonical_url: https://bartvwezel.nl/flutter/switching-cameras-in-flutter/
series: Flutter Camera
cover_image: https://bartvwezel.nl/wp-content/uploads/2022/03/camera-g17b06a5a1_1280-768x771.png
---

In [the last blog post](https://bartvwezel.nl/flutter/taking-pictures-with-flutter/), I show how to take a picture in Flutter using the camera package. In this blog post, I will dive deeper into the camera by explaining how to switch between the different cameras on the phone.

I will start this example with the result of the [previous blog post](https://bartvwezel.nl/flutter/taking-pictures-with-flutter/). In that blog post, I describe all steps necessary to show the camera’s preview and take a picture. One of the steps is to initialize the controller with the first camera. Next, the app looks up all available cameras on the phone during the start-up with the following line of code:

```dart
  cameras = await availableCameras();
```

I always use the same camera description to initialize the controller. Unfortunately, this means the user cannot interact with the other cameras. So let’s change that! The first step is to add a button for each camera. You might use another approach with the increasing number of cameras new devices have, but you can use the same idea.

```dart
class CameraSelectionWidget extends StatelessWidget {
  final CameraDescription selectedCamera;

  const CameraSelectionWidget({Key? key, required this.selectedCamera}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final List<Widget> toggles = [];
    for (final CameraDescription cameraDescription in cameras) {
      toggles.add(
        Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Container(
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Radio<CameraDescription>(
                    groupValue: selectedCamera,
                    value: cameraDescription,
                    onChanged: (value) {
                      //
                    },
                  ),
                  Icon(
                    getCameraLensIcon(cameraDescription.lensDirection, context),
                  ),
                ],
              ),
            )
          ],
        ),
      );
    }
    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: toggles,
      ),
    );
  }
}

IconData getCameraLensIcon(CameraLensDirection direction, BuildContext context) {
  switch (direction) {
    case CameraLensDirection.back:
      return Icons.camera_rear;
    case CameraLensDirection.front:
      return Icons.camera_front;
    case CameraLensDirection.external:
      return Icons.camera;
  }
}
```

This Widget will show all available cameras with a radio button next to them. When the camera is in use, the radio button is active. Furthermore, I determine the icon based on the direction of the camera. However, selecting another camera does not change anything yet. For this, I need to provide a callback to update the controller.

```dart
  void updateController(CameraDescription description) {
    controller?.dispose().then((value) {
      setState(() {});
      controller = CameraController(description, ResolutionPreset.max);
      controller!.initialize().then((_) {
        setState(() {});
      });
    });
  }
```

Here I initialize the controller again and update the Widget when the camera is initialized. To call this method from the camera selection Widget, I need to provide the method to the Camera Selection Widget. I also wrap the preview with a Stack. This makes it possible to draw the camera selection above the preview.

```dart
Stack(
    children: [
      SizedBox(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: CameraPreview(controller!),
      ),
      CameraSelectionWidget(
        selectedCamera: controller!.description,
        onChanged: updateController,
      ),
    ],
    )
```

To handle the function, I need to add it to the constructor method, and then I can call the method when the onchanged of the radio button is triggered.

```dart
class CameraSelectionWidget extends StatelessWidget {
  final CameraDescription selectedCamera;
  final Function(CameraDescription) onChanged;

  const CameraSelectionWidget({Key? key, required this.selectedCamera, required this.onChanged}) : super(key: key);

// and the change in the radio button:

  Radio<CameraDescription>(
    groupValue: selectedCamera,
    value: cameraDescription,
    onChanged: (value) {
      onChanged(value!);
    },
  ),
```

These steps are all that is necessary to switch between cameras in a Flutter application! All of is this is possible thanks to the work of a lot of people on the [camera package](https://pub.dev/packages/camera)! The code of this example is available here on [Github](https://github.com/Barttje/flutter-camera-example).  If you still have any questions, comments, suggestions, remarks, please let me know!

The post [Switching camera’s in Flutter](https://bartvwezel.nl/flutter/switching-cameras-in-flutter/) appeared first on [Barttje](https://bartvwezel.nl).