How to paint in Flutter?

The Custom Paint widget gives us opportunities to paint in Flutter.

You may wonder, what does paint mean in Flutter? Does it mean painting literally with colors and brushes?

Almost that is true.

The CustomPaint widget takes help from CustomPainter abstract class. Why?

Because CustomPainter again extends Listenable so that it not only gives us a canvas where we can paint on, but it creates a custom painter that repaints whenever repaint notifies listeners.

How does it take place?

Through Listenable object the Custom Painter object maintains a list of listeners.

The listeners are typically used to notify clients that the object has been updated.

Let’s take a look at the screenshot first.

We've used paint in Flutter to get a custom home background
We’ve used paint in Flutter to get a custom home background

How we have done that?

Take a look at the code where a subclass extends CustomPainter. Later we’ll use the Shaping Painter custom paint object as a parameter of Custom Paint widget.

class ShapingPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();

    /// setting the paint color grayish
    /// so it could cover the lower half of the screen
    ///
    paint.color = Colors.black12;

    /// Creating a rectangle with size and width same as the canvas
    /// It'll be going to cover the whole screen
    ///
    var rect = Rect.fromLTWH(0, 0, size.width, size.height);

    /// Drawing the rectangle using the paint
    ///
    canvas.drawRect(rect, paint);

    /// Covering the upper half of the rectangle
    ///
    paint.color = Colors.purpleAccent;
    // Firstly, creating a path to form the shape
    var path = Path();
    path.lineTo(0, size.height);
    path.lineTo(size.width, 0);
    // Secondly, closing the path to form a bounded shape
    path.close();
    canvas.drawPath(path, paint);
    // Setting the color property of the paint
    paint.color = Colors.white;
    // Center of the canvas is (x,y) => (width/2, height/2)
    var center = Offset(size.width / 2, size.height / 2);
    // Finally, drawing the circle with center having radius 95.0
    canvas.drawCircle(center, 95.0, paint);
  }

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

Please read the comments above. Hopefully that will clarify how we gradually paint the home page screen according our plan.

Now, we can set this paint as our background.

Moreover, we can change it as we wish.

Here, the CustomPaint and RenderCustomPaint has used the CustomPainter interface.

The paint method is called whenever the custom object needs to be repainted.

Now we can use the subclass in the following way.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //var size = MediaQuery.of(context).size;
    return const MaterialApp(
      title: 'A Custom Home Page',
      home: DashBoard(
          // size: size,
          ),
    );
  }
}

class DashBoard extends StatelessWidget {
  //final Size size;
  const DashBoard({
    Key? key,
    //required this.size,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return MaterialApp(
      title: 'A Custom Home Page',

      /// ignore: todo
      ///TODO: we'll make a custom global theme later
      ///
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.black12,
          leading: const Icon(Icons.menu),
          title: const Text(
            "A Custom Home Page",
            textAlign: TextAlign.center,
          ),
        ),
        body: Stack(
          children: <Widget>[
            Container(
              padding: const EdgeInsets.all(5),
              child: CustomPaint(
                painter: ShapingPainter(),
                child: Container(
                  height: size.height / 1,
                ),
              ),
            ),
            Container(
              margin: const EdgeInsets.only(top: 40),
              child: Padding(
                padding: const EdgeInsets.only(left: 20, right: 20),
                child: GridView.count(
                  crossAxisCount: 2,
                  children: const <Widget>[
                    Text(
                      'We\'ll make a list of GridItems later.',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 30,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

In the above code, we’ve used the Stack and as a Background we used the CustomPaint painter parameter. That implements CustomPainter interface.

CustomPaint is a widget that provides a canvas on which to draw during the paint phase.

Firstly, CustomPaint asks its painter to paint on the current canvas, then it paints its child, and then, after painting its child, it asks its foregroundPainter to paint.

Secondly, the coordinate system of the canvas matches the coordinate system of the CustomPaint object.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

3 responses to “How to paint in Flutter?”

  1. […] keep the custom Custom Paint object in the model folder. This pain object extends abstract class Custom Painter, and builds our […]

  2. […] our model folder we have defined a CustomPaint object that decides how our flutter application will exactly look […]

  3. […] our previous section, we’ve discussed how to paint in Flutter. In this section, we’ll try to learn what is paint in […]

Leave a Reply