The art of sharing screens: Take a ScreenShot and Share it.
Hello Guys!
Hope you are all well, In this, we will learn how to take a screenshot without using the screenshot package and share it with others in Flutter. We’ll go step by step for better understanding.
The flow of this tutorial will be:
- Capture a visible widget.
- Saving a screenshot into your phone and Sharing them.
- Share a screenshot without Saving them into your phone.
Packages that we are using in this tutorial:
- share_plus: (Latest version)
Capture a visible widget and an invisible widget:
First of all, add the share_plus dependency in pubspec.yaml file of your project, under the dependencies, as shown below:
then run this command into your project terminal:
flutter pub add get
Now you have to set minSdkVersion at least 19 because share_plus requires a higher Android SDK version.
file directory: [your_project]\android\app\build.gradle:
Here are the imports that we gonna use!
// For handling byte data and typed arrays (e.g., Uint8List)
import 'dart:typed_data';
// For low-level graphics operations, capturing widgets as images, etc.
import 'dart:ui' as ui;
// Flutter's Material Design framework for building UIs
import 'package:flutter/material.dart';
// For rendering widgets and capturing widget subtrees
import 'package:flutter/rendering.dart';
// For sharing content with other apps on the device
import 'package:share_plus/share_plus.dart';
Now, move on to your widget, where you want to take a screenshot. Inside that widget class make a Global key.
/// Global Key for taking screenShot
final GlobalKey globalKey = GlobalKey();
Wrap your widget with RepaintBoundary(), whom you want to take screenshot and assign the global key to its key property:
RepaintBoundary(
key: globalKey,
child: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Screenshot Page'),
),
body: Center(
child: ElevatedButton(
onPressed: (){},
child: const Text('Take Screenshot'),
),
),
),
);
Now, we need a function that takes a screenshot and shares it:
Future<void> _captureScreenShot() async {
RenderRepaintBoundary boundary =
globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
ui.Image image = await boundary.toImage(pixelRatio: 2);
ByteData byteData =
await image.toByteData(format: ui.ImageByteFormat.png) as ByteData;
Uint8List pngBytes = byteData.buffer.asUint8List();
await Share.shareXFiles([XFile.fromData(pngBytes, mimeType: 'image/png')]);
}
Let’s break down the _captureScreenshot
function step by step:
Step# 01:
RenderRepaintBoundary boundary = globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
- Here, we create a variable named
boundary
of typeRenderRepaintBoundary
. This class allows us to capture a widget subtree and convert it into an image. globalKey.currentContext
returns theBuildContext
associated with theglobalKey
.findRenderObject()
is called on thecurrentContext
, which returns the render object associated with thatBuildContext
.- We use a typecast
as RenderRepaintBoundary
to explicitly convert the rendered object toRenderRepaintBoundary
, as we know that the widget associated withglobalKey
is aRepaintBoundary
.
Step# 02:
ui.Image image = await boundary.toImage(pixelRatio: 2);
- Here, we use the
boundary
object we obtained in the previous step to convert the widget subtree into anui.Image
object. - And
ui
refers to thedart:ui
that we import above. toImage()
is a method ofRenderRepaintBoundary
class that takes an optional parameterpixelRatio
. ThepixelRatio
specifies the scale of the image, which can be used to create higher-resolution screenshots.- In this example, we set
pixelRatio
to 2, which means the screenshot will have twice the resolution compared to the screen's native resolution.
Step# 03:
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png) as ByteData;
- We utilise the
toByteData()
method to change theui.Image
object into aByteData
object after acquiring it. - The format argument, which is optional, is sent to the
toByteData()
function and determines the picture format to use. To obtain the screenshot in PNG format in this instance, we utiliseui.ImageByteFormat.png
. - The data is subsequently saved in the
byteData
variable whentoByteData()
returns its outcome. To clearly state the data type, we typecast asByteData
.
Step# 04:
Uint8List pngBytes = byteData.buffer.asUint8List();
- After obtaining the
ByteData
object, we access the underlying databuffer
, which houses the picture bytes, using the buffer property. - The data buffer is then transformed into an
Uint8List
, which depicts the screenshot as a collection of bytes, using theasUint8List()
function.
Step# 05:
await Share.shareXFiles([XFile.fromData(pngBytes, mimeType: 'image/png')]);
- The screenshot is then shared as a file using the
Share
plugin. - The
share_plus
package has a function calledShare.shareXFiles()
that accepts a list ofXFile
objects as an input. A shareable file is represented by anXFile
. - The
Uint8List
(pngBytes
) holding the image data is passed toXFile.fromData()
when creating anXFile
, and themimeType
is set to‘image/png’
to denote that the file is in PNG format. - The
await
keyword is used to delay doing any more (if necessary) actions until the sharing procedure has finished.
That’s it! With the help of the share_plus
package, this function shares a screenshot it has taken of the widget subtree connected to the globalKey
.
That’s it! With the help of the share_plus package, this function shares a screenshot it has taken of the widget subtree connected to the globalKey.
Conclusion:
In this article, we looked at the technique for sharing screens in a Flutter application by taking a screenshot and doing so. Using the RepaintBoundary widget and the dart:ui library, we discovered how to snap a screenshot of a widget that is now displayed. The widget subtree had to be transformed into an ui.Image, then into ByteData, and then into an Uint8List that represented the image bytes. We quickly shared the screenshot with other applications on the smartphone with the aid of the share_plus package.
Having a grasp of these ideas, you are now able to include screen sharing features in your Flutter apps, facilitating smooth content sharing and user interaction.
Consider purchasing me a coffee if you found this lesson useful and want to support the production of further material. Your support will encourage me to continue producing useful and educational lessons for the community.
I appreciate you joining me on this adventure, and I wish you much success as you discover and develop fantastic Flutter apps! Happy programming!