Building a Drawing App in Flutter
Learn how to create a drawing app in Flutter and explore Flutter’s capability to render and control a custom UI with the help of CustomPaint widgets. By Samarth Agarwal.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Building a Drawing App in Flutter
35 mins
- Getting Started
- Introducing Flutter Canvas and CustomPaint
- Using the CustomPaint Widget
- Understanding Canvas Basics
- Drawing Paths
- Changing the Stroke, Color and Width
- Diving Into Code
- Using GestureDetector
- Drawing a Single Path
- Drawing Multiple Paths
- Adding Stroke Color and Width
- Changing Stroke Color
- Changing Stroke Width
- Optimizing Your App
- Drawing Multiple Lines
- Using StreamBuilders and Two CustomPaint widgets
- Saving the Drawing
- Creating New and Save Buttons
- Using the Plugin
- Where to Go From Here
Saving the Drawing
Now that you have a beautiful drawing, you’ll want to save it to show people later. The RepaintBoundary
returned from buildAllPaths()
will allow us to get the drawing and save it as an image.
Creating New and Save Buttons
While you create the Save button, you’ll also create the New/Clear button to clean the canvas so the user can start over. Add the following code to buildColorToolbar()
:
Widget buildColorToolbar() {
return Positioned(
...
child: Column(
...
children: [
buildClearButton(),
Divider(
height: 10.0,
),
buildSaveButton(),
Divider(
height: 20.0,
),
...
],
),
);
}
In the above code, buildClearButton()
and buildSaveButton()
return two buttons that you add to the color toolbar. Both these methods are already implemented for you.
Save everything and hot restart to see the new buttons in the color toolbar.
Using the Plugin
The New/Clear and Save buttons are now there, but you still need to implement clear()
and save()
. You’ll start with implementing clear()
:
Future<void> clear() async {
setState(() {
lines = [];
line = null;
});
}
In the above code, the lines and line objects are reset to their initial values. This clears all the data about the past drawing, and the UI is rebuilt. The user will now be able to start a fresh drawing!
Finally implement save()
:
Future<void> save() async {
try {
final boundary = _globalKey.currentContext.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage();
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final pngBytes = byteData.buffer.asUint8List();
final saved = await ImageGallerySaver.saveImage(
pngBytes,
quality: 100,
name: DateTime.now().toIso8601String() + ".png",
isReturnImagePathOfIOS: true,
);
} catch (e) {
print(e);
}
}
The code above uses the image_gallery_saver
plugin to save the image to the device’s Gallery (Android) or Photos (iOS). You get the image as a Uint8List
using RepaintBoundary
. Notice how you have defined a key
on the RepaintBoundaryWidget
and used that key
to access the widget in the method above.
At the top of the file, add the necessary imports listed in the code snippet below:
import 'package:flutter/services.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'dart:ui' as ui;
Save everything one last time and perform a complete restart.
That’s all! Congratulations — you now have an amazing drawing app that’s built entirely in Flutter.
Where to Go From Here
Download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.
If you’re in the mood to take on a challenge or two, here are a few more features that you can implement in the drawing app you built:
- Implement Undo/Redo features so that a user can go a step back or forward in their drawing process.
- Add a color picker widget to allow the user to pick a color of their choice instead of being stuck with the provided buttons.
- Create a widget to allow the user to select a precise stroke width.
Here are a couple of articles that will be helpful in learning more about widgets, drawing and animations in Flutter:
- Creating Reusable Custom Widgets in Flutter
- Drawing Custom Shapes With CustomPainter in Flutter
- How to create a 2D Snake Game in Flutter
We hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!