
This article shows you how to programmatically take screenshots in Flutter so that your users can capture their screens by pressing a button or something like that. You can also use this technique to periodically take screenshots of your appÂ’s screens for debug purposes.
Table of Contents
A Quick Instruction
If you feel instructions in words are too confusing and boring, just skip this section and jump to the “The Complete Example” section.Advertisements
Using the RepaintBoundary widget
The taking screenshot action doesnÂ’t require you to install a third-party plugin. The built-in RepaintBoundary widget can help you get the job done. It will create a separate display list for its child.
RepaintBoundary({Key? key, Widget? child})
If you want to capture the entire screen of your app, you can wrap your Scaffold widget inside a RepaintBoundary. Next, you can use the findRenderObject() method to find the current render object. After that, you can use the toImage() (provided by dart:ui > Image class) method to capture an image of the current state of this render object and its children.
Note that you can also use RepaintBoundary to capture only a single widget (just make that widget become a child of RepaintBoundary).
Saving the screenshot
AdvertisementsYou have some options to save the screenshot:
- The photo gallery: You can use the image_gallery_saver to save the screenshot to the gallery folder. The example below will use this method.
- The app documents directory: You can use the path_provider plugin to find commonly used locations on the filesystem.
The Complete Example
App Preview
This sample app contains an elevated button. When the user presses this button, a new screenshot will be created and saved to Gallery.
The Code
1. Installing the image_gallery_saver plugin by executing this command:
flutter pub add image_gallery_saver
We have to ask for permission to access the gallery folder.
IOS: Add the following between <dict></dict> in your <project-directory>/ios/Runner/info.plist file
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app need access to your gallery to save screenshots</string>
Android: Open the manifest file and add this line to your application tag:
<application android_requestLegacyExternalStorage="true" .....>
2. The full code:
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; // In order to use RepaintBoundary, RenderRepaintBoundary
import 'dart:ui' as ui;
import 'dart:typed_data';
// This package is used to save screenshots to the gallery
import 'package:image_gallery_saver/image_gallery_saver.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
theme: ThemeData(primarySwatch: Colors.deepPurple),
home: HomePage());
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// This key is used for the RepaintBoundary widget
final GlobalKey _key = GlobalKey();
String _message = 'Press the button to take a screenshot';
// This function will be triggered when the button is pressed
void _takeScreenshot() async {
RenderRepaintBoundary boundary =
_key.currentContext!.findRenderObject() as RenderRepaintBoundary;
ui.Image image = await boundary.toImage();
ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
if (byteData != null) {
Uint8List pngBytes = byteData.buffer.asUint8List();
// Saving the screenshot to the gallery
final result = await ImageGallerySaver.saveImage(
Uint8List.fromList(pngBytes),
quality: 90,
name: 'screenshot-${DateTime.now()}.png');
print(result);
setState(() {
_message = 'New screenshot successfully saved!';
});
}
}
@override
Widget build(BuildContext context) {
return RepaintBoundary(
key: _key,
child: Scaffold(
backgroundColor: Colors.amber,
appBar: AppBar(
title: Text('Kindacode.com'),
),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: _takeScreenshot, child: Text('Take Screenshot')),
SizedBox(
height: 20,
),
Text(_message)
],
),
),
),
);
}
}
Conclusion
WeÂ’ve gone through a complete example of taking screenshots from within a Flutter app. If youÂ’d like to explore more new and interesting things about Flutter and the mobile development area, have a look at the following articles:
- Flutter Web: 2 Ways to Change Page Title Dynamically
- Using GetX (Get) for State Management in Flutter
- Flutter PaginatedDataTable Example
- Flutter and Firestore Database: CRUD example (null safety)
- Flutter + Firebase Storage: Upload, Retrieve, and Delete files
- 4 Ways to Store Data Offline in Flutter
You can also check out our Flutter category page, or Dart category page for the latest tutorials and examples.