Flutter Custom Paint Tutorial | Draw a Custom Shape Path in Flutter

Ravi Shankar Singh
DevMins
Published in
4 min readJan 5, 2019

Flutter is creating a Boom in the market and getting a lot of attention nowadays! Like everything related to flutter UI, drawing the custom shape on canvas is easy too.

We will be creating a screen similar to this…

#1

Throughout this tutorial, I will assume that you have a little bit of experience with flutter..though I will try to explain the basics as much as I can along the way. Let's start with the tutorial.

import 'package:flutter/material.dart';
import 'theme/colors.dart';
import 'top_bar.dart';

void main(){
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Curved Path',
theme: appTheme,
home: HomePage(),
);
}
}

The first method that gets called is main() method and this method will call runApp(MyApp) with our root widget which returns a MaterialApp.Let's go ahead and define the HomePage widget that we have mentioned in the home property of MaterialApp.

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: TopBar(),
),
);
}
}

Now, I have a Scaffold widget, Scaffold manages the layout of the general components of a Material design app in the flutter. I have a body with Container widget which has a child that contains the Custom Shape defined inside a separate file i.e top_bar.dart.

Before creating the top_bar.dart .Let's have a look into colors.dart in which app theme and some colors are defined which we are going to use inside our top_bar.dart file.

import 'dart:ui';
import 'package:flutter/material.dart';

Color colorOne = Colors.red;
Color colorTwo = Colors.red[300];
Color colorThree = Colors.red[100];

final appTheme = ThemeData(
primarySwatch: Colors.red,
);

I have used three different shades of the same color so that we can have different shapes one over other with the growing intensity of color.

Now let's go ahead and define top_bar.dart file.

import 'package:flutter/material.dart';
import 'theme/colors.dart';

class TopBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomPaint(
child: Container(
height: 300.0,
),
painter: CurvePainter(),
);
}
}

I have defined the TopBar class with height 300.0, Now let's define CurvePainter class.

class CurvePainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
Path path = Path();
Paint paint = Paint();


path.lineTo(0, size.height *0.75);
path.quadraticBezierTo(size.width* 0.10, size.height*0.70, size.width*0.17, size.height*0.90);
path.quadraticBezierTo(size.width*0.20, size.height, size.width*0.25, size.height*0.90);
path.quadraticBezierTo(size.width*0.40, size.height*0.40, size.width*0.50, size.height*0.70);
path.quadraticBezierTo(size.width*0.60, size.height*0.85, size.width*0.65, size.height*0.65);
path.quadraticBezierTo(size.width*0.70, size.height*0.90, size.width, 0);
path.close();

paint.color = colorThree;
canvas.drawPath(path, paint);

path = Path();
path.lineTo(0, size.height*0.50);
path.quadraticBezierTo(size.width*0.10, size.height*0.80, size.width*0.15, size.height*0.60);
path.quadraticBezierTo(size.width*0.20, size.height*0.45, size.width*0.27, size.height*0.60);
path.quadraticBezierTo(size.width*0.45, size.height, size.width*0.50, size.height*0.80);
path.quadraticBezierTo(size.width*0.55, size.height*0.45, size.width*0.75, size.height*0.75);
path.quadraticBezierTo(size.width*0.85, size.height*0.93, size.width, size.height*0.60);
path.lineTo(size.width, 0);
path.close();

paint.color = colorTwo;
canvas.drawPath(path, paint);

path =Path();
path.lineTo(0, size.height*0.75);
path.quadraticBezierTo(size.width*0.10, size.height*0.55, size.width*0.22, size.height*0.70);
path.quadraticBezierTo(size.width*0.30, size.height*0.90, size.width*0.40, size.height*0.75);
path.quadraticBezierTo(size.width*0.52, size.height*0.50, size.width*0.65, size.height*0.70);
path.quadraticBezierTo(size.width*0.75, size.height*0.85, size.width, size.height*0.60);
path.lineTo(size.width, 0);
path.close();

paint.color = colorOne;
canvas.drawPath(path, paint);
}

@override
bool shouldRepaint(CustomPainter oldDelegate) {
return oldDelegate != this;
}

}

CurvePainter class extends CustomPainter and overrides paint method and shouldRepaint method. I have drawn three paths one over other with three different colors inside the paint method.

Inside of paint method, we define a path and paint that will be used to draw a path on the canvas. A Path is used to define the path on which we want to draw.

We call lineTo method on a path to add a straight line segment from the current point to the given point. And then adds a quadratic Bezier segment that curves from the current point to the given point (x2,y2), using the control point (x1,y1).In final path.close() is called to close that path and a new color is set on paint.

paint.color = colorOne;
canvas.drawPath(path, paint);

At last drawPath method is called on canvas to draw the path with the coordinates we have set.

The Path path = Path(); is created three times so that we can have three different layers of custom shapes.

That's what we need to build this simple piece of UI, which can be used in many places!

Youtube tutorial video link :

Video tutorial by Techie Blossom

--

--