FlutterWorld
Published in

FlutterWorld

Flutter: Analog clock coding with CustomPaint

Flutter came with a lot of widgets in his pockets. Buttons, icons, containers, and many other widgets that are very easy to include in your code to get a beautifully designed app. But sometimes you wish to create a very, very custom user interface. In that case, the CustomPaint widget is your best choice. With this widget, you have access to low-level paint calls. These are fast and efficient, and let you build slick graphics. For example, the Material ink ripple effect is implemented using a circle.

So all you have to do is to add a CustomPaint widget to your widget tree. Give it a size (optional) and a painter. Then implement your painter. It’s a class that extends CustomPainter and implements two methods: paint and shouldRepaint.

The CustomPaint widget uses the painter to paint on the current canvas, then it paints its child. The should repaint method is called when the CustomPainter is rebuilt. You can tell the framework to reuse the previous result of paint.

CustomPaint(
painter: MyPainter(),
child: Center(
child: Text('Paint behind me !',
style: const TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
),
)

The paint method is where you get your canvas, and is free to draw.

So, let’s draw a rectangle :

class MyPainter extends CustomPainter {  @override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
//Draw a rectangle
canvas.drawRect(Offset(150, 100) & Size(200, 150), paint);
}

@override
bool shouldRepaint(MyPainter oldDelegate) => false;

}

We have given to the rectangle an offset of (150, 100). The top-left coordinates of the rectangle are (150, 100). The top left corner of the canvas has an offset of (0, 0). The rectangle has a size of (200, 150). 200 is the width and 150 is the height.

The rectangle is rendered onto the canvas using the paint defined by this object. You may change the stroke color, the fill color and style, and many other properties using this paint object.

If we don’t expect any changes we can return false in the should repaint method.

You can draw lines, rectangles, circles, arcs, paths, bitmap images, and even paragraphs of text. And you have full control over how to paint these colors, shaders, blend modes, and more.

Enough talking and let’s start with our analog clock. Here is the home screen code :

Nothing special. Now we will create our FlutterAnalogClock statefulWidget:

In the initState method, we get the current time value and store it in the _dateTime variable, then we create a timer that executes an anonymous function every second. In this function, we increment the _dateTime value by one second and execute the setState method to trigger the clock repaint. This is what makes the clock animated.

Next, we will create the painter FlutterAnalogClockPainter which has as parameters the _dateTime and the _borderWidth:

In this class, we are mainly using the current _dateTime value and the mathematical formula of rotation to draw the three clock hands using different lengths and strokes width.

When the canvas “should repaint”? If there is a change in the border width of the clock or in the _dateTime value which happens every one second.

The full source code is here.

You can go further by customizing the sizes and the colors of the different parts of the clock. If you want more analog clocks for flutter, check here.

Thank you for reading this article. Please, if you like it, share it.

See also:

--

--

--

The fastest growing community which makes development easier

Recommended from Medium

How To Avoid Android System Navigation Bar Overlapping Views at the bottom

Android Room+MVVM Part 1: Room, ViewModel and RecyclerView

Android: Coroutines with Blinking TextView

An Effective Way to Update List in RecyclerView (Using AsyncListDiffer — DiffUtil)

REGEDDIT MOBILE — FF

A lightweight tooltip popup for Android

UnsatisfiedLinkError: No implementation found for long org.opencv.core.Mat.n_Mat()

Android Compose UI: ViewModel + Hilt Dependency Injection

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ouzani Abd Raouf

Ouzani Abd Raouf

Computer Science Engineer and Cisco Instructor

More from Medium

Flutter for Mobile App Development creating a buzz in Startups

Build a Beautiful Navigation Drawer/Sidebar Menu in Flutter

How to get your Flutter app to the App Store

What's new in Flutter 3?🤩