skip to Main Content

I want to create a custom timer widget in flutter. The timer should be at the center of the circle and the border of the circle should decrease as the timer decreases. Their should be a circular spot at the end of the border form where it is reducing. I want to apply gradient colors to the border of the circle.

I tried it using Circular progress indicator of flutter but I can’t change the color of border to gradient and I can’t put the spot at the reducing edge of the circle.

2

Answers


  1. It seems like you’re looking for a custom timer widget in Flutter using the percent_indicator package with gradient colors for the border and a timer at the Center of the circle. Here’s a formatted and slightly improved version of the provided example:

    CircularPercentIndicator(
      radius: screenWidth / 4,
      lineWidth: 5.0,
      percent: 0.75,
      center: Text(
        "75%",
        style: TextStyle(color: Color(0xFF535355)),
      ),
      linearGradient: LinearGradient(
        begin: Alignment.topRight,
        end: Alignment.bottomLeft,
        colors: <Color>[Color(0xFF1AB600), Color(0xFF6DD400)],
      ),
      rotateLinearGradient: true,
      circularStrokeCap: CircularStrokeCap.round,
    )
    

    Add Your Timer Text Into Text Widget And Percent Field In Widget.

    Login or Signup to reply.
  2. Please check this code snippet

        import 'package:flutter/material.dart';
        import 'dart:math';
    
        void main() {
          runApp(MyApp());
        }
    
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
             home: Scaffold(
                appBar: AppBar(
                 title: const Text('Custom Timer     Widget'),
                ),
                body: const Center(
              child: CustomTimerWidget(
                duration: Duration(seconds: 10),
              ),
            ),
          ),
        );
         }
        }
    
        class CustomTimerWidget extends StatefulWidget {
        final Duration duration;
    
        const CustomTimerWidget({required this.duration});
    
        @override
        _CustomTimerWidgetState createState() => _CustomTimerWidgetState();
        }
    
        class _CustomTimerWidgetState extends State<CustomTimerWidget>
        with TickerProviderStateMixin {
          late AnimationController _controller;
          late Animation<double> _animation;
    
          @override
          void initState() {
          super.initState();
          _controller = AnimationController(
          vsync: this,
          duration: widget.duration,
          )..forward();
    
          _animation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
         }
    
         @override
          Widget build(BuildContext context) {
            return AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
                return Container(
              width: 200,
              height: 200,
              child: CustomPaint(
                painter: TimerPainter(progress: _animation.value),
                child: Center(
                  child: Text(
                    '${(_animation.value * widget.duration.inSeconds).ceil()}s',
                    style: TextStyle(fontSize: 20.0, color: Colors.black),
                  ),
                ),
              ),
            );
          },
          );
        }
    
        @override
          void dispose() {
        _controller.dispose();
          super.dispose();
          }
        }
    
        class TimerPainter extends CustomPainter {
        final double progress;
    
        TimerPainter({required this.progress});
    
        @override
          void paint(Canvas canvas, Size size) {
        final double strokeWidth = 10.0;
        final double radius = (size.shortestSide - strokeWidth) / 2;
    
        Paint outerCircle = Paint()
          ..strokeWidth = strokeWidth
          ..color = Colors.grey[300]!
          ..style = PaintingStyle.stroke;
    
        Paint gradientCircle = Paint()
          ..strokeWidth = strokeWidth
          ..shader = LinearGradient(
            colors: [Colors.blue, Colors.red],
          ).createShader(Rect.fromCircle(
              center: Offset(size.width / 2, size.height / 2), radius: radius))
          ..style = PaintingStyle.stroke;
    
        Paint spotPaint = Paint()
          ..color = Colors.black
          ..strokeWidth = 2.0
          ..style = PaintingStyle.fill;
    
        canvas.drawCircle(
            Offset(size.width / 2, size.height / 2), radius, outerCircle);
        canvas.drawArc(
          Rect.fromCircle(
              center: Offset(size.width / 2, size.height / 2), radius: radius),
          -pi / 2,
          pi * 2 * progress,
          false,
          gradientCircle,
        );
    
        // Draw a circular spot at the end of the border
        double spotX = size.width / 2 + radius * cos(pi * 2 * progress - pi / 2);
        double spotY = size.height / 2 + radius * sin(pi * 2 * progress - pi / 2);
        canvas.drawCircle(Offset(spotX, spotY), strokeWidth / 2, spotPaint);
      }
    
        @override
        bool shouldRepaint(covariant CustomPainter oldDelegate) {
            return true;
         }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search