Analog Clock in Flutter: A Step-by-Step Guide with Example

Flutter is a popular open-source UI software development toolkit created by Google. It allows developers to build beautiful and high-performance mobile, web, and desktop applications from a single codebase. In this tutorial, we will explore how to create an analog clock using Flutter, making use of the Flutter framework's powerful and flexible widgets.

Prerequisites

Before we dive into the tutorial, make sure you have the following:

  1. Flutter SDK installed on your machine. You can download it from the official Flutter website and follow the installation instructions for your operating system.
  2. A basic understanding of Flutter widgets and how to set up a Flutter project.


Example 1 Analog Clock Using CustomPainter


Step 1: Create a New Flutter Project

To get started, open your terminal or command prompt and create a new Flutter project using the following command:

flutter create analog_clock_flutter 

This will create a new Flutter project named 'analog_clock_flutter' with the necessary project structure.

Step 2: Design the Analog Clock UI

Now, navigate to the 'lib' folder of your project and open the 'main.dart' file. We will create a custom widget for our analog clock, so remove the default 'MyApp' widget and replace it with the following code:

import 'dart:math';


import 'package:flutter/material.dart';


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


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


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark(),
      home: const AnalogClock(),
    );
  }
}


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


  @override
  _AnalogClockState createState() => _AnalogClockState();
}


class _AnalogClockState extends State<AnalogClock> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        title: const Text('FlutterforGeeks'),
      ),
      body: Center(
        child: Column(
          children: [
            const SizedBox(
              height: 30,
            ),
            const Text(
              'Analog Clock',
              style: TextStyle(fontSize: 24),
            ),
            const SizedBox(
              height: 200,
            ),
            SizedBox(
              width: 200,
              height: 200,
              child: CustomPaint(
                painter: ClockPainter(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Step 3: Implement the Analog Clock CustomPainter

In the 'ClockPainter' class, we will implement the custom painting for our analog clock. We will draw the clock face, hour, minute, and second hands. Update the 'paint' method in the 'ClockPainter' class with the following code:

class ClockPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // Draw clock face
    final centerX = size.width / 2;
    final centerY = size.height / 2;
    final centerOffset = Offset(centerX, centerY);
    final radius = size.width / 2;
    final facePaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;
    canvas.drawCircle(centerOffset, radius, facePaint);


    // Draw hour hand
    final hourHandPaint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 6;
    final hour = DateTime.now().hour;
    final hourRadians = -(hour * 30 - 90) * (pi / 180);
    final hourHandX = centerX + (radius - 40) * cos(hourRadians);
    final hourHandY = centerY + (radius - 40) * sin(hourRadians);
    final hourHandOffset = Offset(hourHandX, hourHandY);
    canvas.drawLine(centerOffset, hourHandOffset, hourHandPaint);


    // Draw minute hand
    final minuteHandPaint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 4;
    final minute = DateTime.now().minute;
    final minuteRadians = -(minute * 6 - 90) * (pi / 180);
    final minuteHandX = centerX + (radius - 30) * cos(minuteRadians);
    final minuteHandY = centerY + (radius - 30) * sin(minuteRadians);
    final minuteHandOffset = Offset(minuteHandX, minuteHandY);
    canvas.drawLine(centerOffset, minuteHandOffset, minuteHandPaint);


    // Draw second hand
    final secondHandPaint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;
    final second = DateTime.now().second;
    final secondRadians = -(second * 6 - 90) * (pi / 180);
    final secondHandX = centerX + (radius - 20) * cos(secondRadians);
    final secondHandY = centerY + (radius - 20) * sin(secondRadians);
    final secondHandOffset = Offset(secondHandX, secondHandY);
    canvas.drawLine(centerOffset, secondHandOffset, secondHandPaint);
  }


  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

Step 4: Run the App

Save your changes and run the app using the following command:

flutter run 

You should now see a beautiful analog clock with moving hour, minute, and second hands!

Step 5: Complete Source Code

import 'dart:math';


import 'package:flutter/material.dart';


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


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


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.dark(),
      home: const AnalogClock(),
    );
  }
}


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


  @override
  _AnalogClockState createState() => _AnalogClockState();
}


class _AnalogClockState extends State<AnalogClock> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        title: const Text('FlutterforGeeks'),
      ),
      body: Center(
        child: Column(
          children: [
            const SizedBox(
              height: 30,
            ),
            const Text(
              'Analog Clock',
              style: TextStyle(fontSize: 24),
            ),
            const SizedBox(
              height: 200,
            ),
            SizedBox(
              width: 200,
              height: 200,
              child: CustomPaint(
                painter: ClockPainter(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}


class ClockPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // Draw clock face
    final centerX = size.width / 2;
    final centerY = size.height / 2;
    final centerOffset = Offset(centerX, centerY);
    final radius = size.width / 2;
    final facePaint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;
    canvas.drawCircle(centerOffset, radius, facePaint);


    // Draw hour hand
    final hourHandPaint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 6;
    final hour = DateTime.now().hour;
    final hourRadians = -(hour * 30 - 90) * (pi / 180);
    final hourHandX = centerX + (radius - 40) * cos(hourRadians);
    final hourHandY = centerY + (radius - 40) * sin(hourRadians);
    final hourHandOffset = Offset(hourHandX, hourHandY);
    canvas.drawLine(centerOffset, hourHandOffset, hourHandPaint);


    // Draw minute hand
    final minuteHandPaint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 4;
    final minute = DateTime.now().minute;
    final minuteRadians = -(minute * 6 - 90) * (pi / 180);
    final minuteHandX = centerX + (radius - 30) * cos(minuteRadians);
    final minuteHandY = centerY + (radius - 30) * sin(minuteRadians);
    final minuteHandOffset = Offset(minuteHandX, minuteHandY);
    canvas.drawLine(centerOffset, minuteHandOffset, minuteHandPaint);


    // Draw second hand
    final secondHandPaint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;
    final second = DateTime.now().second;
    final secondRadians = -(second * 6 - 90) * (pi / 180);
    final secondHandX = centerX + (radius - 20) * cos(secondRadians);
    final secondHandY = centerY + (radius - 20) * sin(secondRadians);
    final secondHandOffset = Offset(secondHandX, secondHandY);
    canvas.drawLine(centerOffset, secondHandOffset, secondHandPaint);
  }


  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}



GitHub Repository - Find the complete code for each example in this tutorial on GitHub.


Example 2 Analog Clock Using analog_clock Plugin


Step 1: Create a New Flutter Project

To begin, open your terminal or command prompt and create a new Flutter project using the following command:

flutter create analog_clock_flutter 

Navigate into the project directory:

cd analog_clock_flutter 

Step 2: Add the analog_clock Plugin

Open the pubspec.yaml file in your project, and under the dependencies section, add the analog_clock plugin:

dependencies:
  flutter:
    sdk: flutter
  analog_clock: ^1.0.0

Save the file and run the following command in your terminal to get the new plugin:

flutter pub get 

Step 3: Design the Analog Clock UI

Now, open the main.dart file located in the lib folder. Replace the default code with the following:

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


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


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Analog Clock'),
        ),
        body: Center(
          child: AnalogClock(
            decoration: BoxDecoration(
                    border: Border.all(width: 3.0, color: Colors.black),
                    color: Colors.black,
                    shape: BoxShape.circle), // decoration
                width: 200.0,
                height: 200,
                isLive: true,
                hourHandColor: Colors.white,
                minuteHandColor: Colors.white,
                showSecondHand: true,
                numberColor: Colors.white,
                showNumbers: true,
                textScaleFactor: 1.5,
                showTicks: true,
                showDigitalClock: true,
                digitalClockColor: Colors.white,
                datetime: DateTime(2020, 8, 4, 9, 11, 0),
          ),
        ),
      ),
    );
  }
}

Step 4: Run the App

Save your changes and run the app using the following command:

flutter run 

Voilà! You should now see a stunning analog clock ticking away on your screen.


Video Demo


Conclusion

In this tutorial, we have learned how to create an analog clock in Flutter using the CustomPainter class. We utilized Flutter's powerful drawing capabilities to design the clock face and hands. With this foundation, you can further customize and enhance the clock to fit your specific needs.

Remember that this is just one way to create an analog clock in Flutter, and there are many possibilities for customization and refinement. I encourage you to experiment further with Flutter's widgets and explore its vast ecosystem to build even more impressive and engaging user interfaces.

Happy coding!

Description of the image

Related Posts