Skip to content
Articles
Article

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

techscript24.com

<p class="image-align-center"><img alt="" height="599" src="http://techscript24.com/admin/UI/assets/img/BlogsImage/Screenshot 2019-01-06 at 1.02.01 AM.png" width="1000" /></p> <p>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.</p> <p>We will be creating a screen similar to this…</p> <p><img alt="" height="786" src="https://cdn-images-1.medium.com/max/800/1*houL4Gr3PMJj7hrYmrSQug.png" width="373" /></p> <p>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&#39;s start with the tutorial.</p> <pre> <code class="language-java">import 'package:flutter/material.dart'; import 'theme/colors.dart'; import 'top_bar.dart'; void main(){ runApp(MyApp()); }</code></pre> <pre> <code class="language-java">class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Curved Path', theme: appTheme, home: HomePage(), ); } }</code></pre> <p>The first method that gets called is <strong>main()</strong> method and this method will call <strong>runApp(MyApp)</strong> with our root widget which returns a <strong>MaterialApp</strong>.Let&#39;s go ahead and define the HomePage widget that we have mentioned in the home property of <strong>MaterialApp</strong>.</p> <pre> <code class="language-java">class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( body: Container( child: TopBar(), ), ); } }</code></pre> <p>Now, I have a <strong>Scaffold </strong>widget, Scaffold manages the layout of the general components of a Material design app in the flutter. I have a body with <strong>Container</strong> widget which has a child that contains the Custom Shape defined inside a separate file i.e <strong>top_bar.dart</strong>.</p> <p>Before creating the top_bar.dart.Let&#39;s have a look into <strong>colors.dart</strong> in which app theme and some colors are defined which we are going to use inside our top_bar.dart file.​</p> <pre> <code class="language-java">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, );</code></pre> <p>​​​​​​</p> <p>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.</p> <p>Now let&#39;s go ahead and define top_bar.dart file.</p> <pre> <code class="language-java">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(), ); } }</code></pre> <p>​​​​​​</p> <p>I have defined the TopBar class with height 300.0, Now let&#39;s define CurvePainter class.</p> <pre> <code class="language-java">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; } }</code></pre> <p>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.</p> <p>Inside of paint method, we define a path and paint that will be used to draw a path on the canvas. A<strong> Path</strong> is used to define the path on which we want to draw.</p> <p>We call the<strong> lineTo</strong> 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.</p> <blockquote> <p>paint.<strong>color </strong>= colorOne;<br /> canvas.drawPath(path, paint);</p> </blockquote> <p>At last drawPath method is called on canvas to draw the path with the coordinates we have set.</p> <blockquote> <p>The Path path = Path(); is created three times so that we can have three different layers of custom shapes.</p> </blockquote> <p>That&#39;s what we need to build this simple piece of UI, which can be used in many places!</p> <p><strong>Youtube tutorial video link:</strong> <a href="https://youtu.be/hTxQ3uNC_oU" target="_blank">https://youtu.be/hTxQ3uNC_oU</a></p> <p>Github repository: <a href="https://github.com/ravishankarsingh1996/custom_shape_background" target="_blank">https://github.com/ravishankarsingh1996/custom_shape_background</a></p> <p><strong><em>If you liked what you read, please leave some claps!</em></strong></p> <p><strong><em>Follow me:</em></strong></p> <p>T<strong>witter :</strong> <a href="https://twitter.com/imRaviSSingh" target="_blank">https://twitter.com/imRaviSSingh</a></p> <p>F<strong>acebook :</strong> <a href="https://www.facebook.com/itsravishankarsingh" target="_blank">https://www.facebook.com/itsravishankarsingh</a></p> <p>I<strong>nstagram :</strong> <a href="https://www.instagram.com/itsravishankarsingh/" target="_blank">https://www.instagram.com/itsravishankarsingh/</a></p> <p>G<strong>ithub : </strong><a href="https://github.com/ravishankarsingh1996" target="_blank">https://github.com/ravishankarsingh1996</a></p>

Forum

Questions about this, or something to add?

Discuss on the forum

Topics CustomPainter

Report this · Wrote this? Claim it

Supported by