Sharing: How to Draw a Line in Flutter

Charles Bintang
3 min readMay 14, 2024

Hi, I hope you are doing well. I will share my experience on how to draw a line in Flutter. As additional information, I am using Linux operating system, so please adjust it to your computer or operating system.

Main Content

I will divide this topic into 4 parts:

  1. Initial Setup
  2. Create Necessary Classes
  3. Implementing the Draw a Line Functionality
  4. Conclusion

Let’s ngoding!

Initial Setup

First, make sure Flutter is installed on your computer. If not installed, please download and install flutter from the Flutter official website. Then create a new project in flutter by typing the following code in the terminal.

flutter create flutter_drawing_line

Create Necessary Classes

Create a new file in the lib directory called brush.dart and fill in the code in the file as follows:

import 'package:flutter/material.dart';

class Brush extends StatefulWidget {
const Brush({super.key});

@override
State<Brush> createState() => _BrushState();
}

class _BrushState extends State<Brush> {
List<Points> points = [];

@override
Widget build(BuildContext context) {
return Scaffold();
}
}

The Brush class will be our foundation in creating this application. To create a line, we must understand that lines are connected points. This image comes from arsitur.com which can be an illustration for you.

In Flutter, the Canvas class provides what’s needed to draw a line.

import 'package:flutter/material.dart';

class Points {
Offset? offset;
Paint? paint;

Points({
this.offset,
this.paint,
});
}

The purpose of creating the Points class, is to draw the points that we will combine later in the DrawingLine class. The following is the DrawingLine class:

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_drawing_line/points.dart';

class DrawingLine extends CustomPainter {
final List<Points> drawingPoints;

DrawingLine(this.drawingPoints);
List<Offset> offsetList = [];

@override
void paint(Canvas canvas, Size size) {
for (var i = 0; i < drawingPoints.length - 1; i++) {
if (drawingPoints[i].offset != null &&
drawingPoints[i + 1].offset != null) {

canvas.drawLine(
drawingPoints[i].offset as Offset,
drawingPoints[i + 1].offset as Offset,
drawingPoints[i].paint as Paint);

} else if (drawingPoints[i].offset != null &&
drawingPoints[i + 1].offset == null) {

offsetList.clear();
offsetList.add(drawingPoints[i].offset as Offset);
canvas.drawPoints(
PointMode.points, offsetList, drawingPoints[i].paint as Paint);
}
}
}

@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

The purpose of the DrawingLine class is to draw a line at 2 adjacent points. However, if the next point is null, then only the point will be drawn.

Implementing the Draw a Line Functionality

First, change the code in lib/main.dart:

import 'package:flutter/material.dart';
import 'package:flutter_drawing_line/brush.dart';

void main() {
runApp(const MainApp());
}

class MainApp extends StatelessWidget {
const MainApp({super.key});

@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Brush(),
);
}
}

Next, open the brush.dart file again and add these functions inside the _BrushState class. Don’t forget to import the DrawingLine and Points classes.

import 'package:flutter/material.dart';
import 'package:flutter_drawing_line/drawing_line.dart';
import 'package:flutter_drawing_line/points.dart';

...
class _BrushState extends State<Brush> {
...
void brushOnPanStart(DragStartDetails details) {
setState(() {
points.add(
Points(
offset: details.localPosition,
paint: Paint()
..color = Colors.black
..isAntiAlias = true
..strokeWidth = 0.5
..strokeCap = StrokeCap.round,
),
);
});
}

void brushOnPanUpdate(DragUpdateDetails details) {
setState(() {
points.add(Points(
offset: details.localPosition,
paint: Paint()
..color = Colors.black
..isAntiAlias = true
..strokeWidth = 0.5
..strokeCap = StrokeCap.round,
));
});
}

void brushOnPanEnd(DragEndDetails details) {
setState(() {
points.add(Points(offset: null, paint: null));
});
}

List<Widget> dataStack() {
List<Widget> data = [];
for (var i = 0; i < points.length; i++) {
data.add(
CustomPaint(
painter: DrawingLine(points),
),
);
}
return data;
}
...

The point of these functions is to make it easier for us to draw a point and save it. Finally, let’s implement these functions, and run the application in the terminal.

class _BrushState extends State<Brush> {
...
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
body: Center(
child: GestureDetector(
onPanStart: (DragStartDetails details) => brushOnPanStart(details),
onPanUpdate: (DragUpdateDetails details) => brushOnPanUpdate(details),
onPanEnd: (DragEndDetails details) => brushOnPanEnd(details),
child: Container(
width: 300,
height: 500,
color: Colors.white,
child: Stack(
children: dataStack(),
),
),
),
),
);
}
}
flutter run

Done! The app is running and functioning as expected.

Conclusion

You’ve successfully created a Drawing Line app in Flutter! This app allows users to draw a line on the screen. The disadvantage of this app is the absence of state management which results in the application will be slower to respond or draw new lines.

The complete source code is here

Learn the classes in Flutter, and keep learning!

--

--