How to create Linear and Circular Progress bars in Flutter

Flutter Jul 23, 2023

Progress bars are useful components in mobile applications that show how far a task is done or how much of a goal has been achieved. In Flutter, you can easily create attractive and customizable progress bars using the percent_indicator package. This package provides two main widgets: LinearPercentIndicator for horizontal progress bars and CircularPercentIndicator for circular ones. These widgets allow you to customize the appearance of the progress bars, making it easy to create visually appealing and informative progress indicators for your application.

Installing

To get started with implementing, we need to install the percent_indicator package into our project. The installation process is simple. Just execute the following command: flutter pub add percent_indicator.

Once the command is executed, make sure to check your pubspec.yaml file for the added dependencies. You should see the percent_indicator package included in the dependencies section, like this:

dependencies:
  flutter:
    sdk: flutter
  percent_indicator: ^4.2.3

Linear progress bar

We will start by implementing a regular linear progress bar using the LinearPercentIndicator widget. This widget is very flexible and lets you customize how the progress bar looks and behaves in many ways.

import 'package:flutter/material.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Progress bar demo'),
        ),
        body: Center(
          child: LinearPercentIndicator(
            alignment: MainAxisAlignment.center,
            barRadius: Radius.circular(25),
            center: Text(
              '25.5%',
              style: TextStyle(fontSize: 20),
            ),
            lineHeight: 25,
            percent: 0.255,
            progressColor: Colors.green,
            width: MediaQuery.of(context).size.width * 0.90,
          ),
        ),
      ),
    );
  }
}

In this code snippet, we created a very simple application that displays one page using the Scaffold widget. In the body of the Scaffold widget, we have a LinearPercentIndicator widget which will display the progress bar. The progress bar is horizontally centered (alignment: MainAxisAlignment.center) and has rounded corners with a circular radius of 25 (barRadius: Radius.circular(25)).

At the center of the progress bar, a Text widget shows "25.5%" with a font size of 20. This text represents the percentage and provides a visual indication of the progress.

The height of the progress bar line is set to 25 (lineHeight: 25), and the percent property has a value of 0.255, matching the 25.5% completion.

The progress bar is colored green (progressColor: Colors.green), and its width is calculated to be 90% (width: MediaQuery.of(context).size.width * 0.90).

When you run the application, it will display the linear progress bar with the green progress line representing the 25.5% completion. The progress bar is visually centered with rounded edges, and the center text provides a clear indication of the current progress toward the goal.

flutter_linear_percent_indicator_progress_bar

The LinearPercentIndicator widget comes with quite a lot of properties, click here for the list.

  1. addAutomaticKeepAlive: Whether to preserve the state of the progress bar. (Type: bool)
  2. alignment: The alignment of the indicator when it does not fill the entire width of the parent widget. (Type: MainAxisAlignment)
  3. animateFromLastPercent: Whether to animate from the last percentage value or start from 0%. (Type: bool)
  4. animation: Whether to animate the progress bar. (Type: bool)
  5. animationDuration: The duration of the animation. (Type: Duration)
  6. backgroundColor: The background color of the progress bar. (Type: Color)
  7. barRadius: The corner radius and style of the progress bar. (Type: Radius)
  8. center: A widget to display in the center of the progress bar. (Type: Widget)
  9. clipLinearGradient: Whether to clip the gradient to the bounds of the progress bar. (Type: bool)
  10. curve: Set a linear curve animation type. (Type: Curve)
  11. fillColor: The color of the whole background, the default is transparent. (Type: Color)
  12. isRTL: Whether to display the progress bar from right to left. (Type: bool)
  13. leading: A widget to display before the progress bar. (Type: Widget)
  14. linearGradient: A gradient to apply to the progress bar. (Type: LinearGradient)
  15. linearGradientBackgroundColor: First color applied to the complete line. (Type: LinearGradient)
  16. lineHeight: The height of the progress bar line. (Type: double)
  17. maskFilter: A mask filter to apply to the progress bar. (Type: MaskFilter)
  18. onAnimationEnd: A callback function that is called when the animation completes. (Type: VoidCallback)
  19. padding: The padding around the progress bar. (Type: EdgeInsets)
  20. percent: The percentage value to show in the progress bar. (Type: double)
  21. progressColor: The color of the progress bar. (Type: Color)
  22. restartAnimation: Restarts the animation when the value reaches 1.0. (Type: bool)
  23. trailing: A widget to display after the progress bar. (Type: Widget)
  24. widgetIndicator: A custom widget indicator to use instead of the default line. (Type: Widget)
  25. width: The width of the progress bar. (Type: double)

Circular progress bar

Next, let us explore the CircularPercentIndicator, which presents a circular progress bar. This widget is equally customizable and offers various properties to control its appearance and animation.

import 'package:flutter/material.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Progress bar demo'),
        ),
        body: Center(
          child: CircularPercentIndicator(
            lineWidth: 30.0,
            percent: 0.255,
            progressColor: Colors.green,
            radius: 100,
            center: Text(
              '25.5%',
              style: TextStyle(fontSize: 30),
            ),
          ),
        ),
      ),
    );
  }
}

In this code snippet, we created a circular progress indicator by using the CircularPercentIndicator class. This widget has a width of 30.0 (lineWidth: 30.0). The completion percentage is set to 0.255 (percent: 0.255), which represents 25.5%.

The progress bar is colored green (progressColor: Colors.green), indicating the progress towards the target.

The circular progress indicator has a radius of 100 (radius: 100), making it quite large.

In the center of the circular progress indicator, there is a Text widget displaying "25.5%" with a font size of 30 (style: TextStyle(fontSize: 30)). This text represents the current percentage completion and is placed at the center of the circular progress indicator.

When you run the application, it will display the circular progress bar with the green progress line representing the 25.5% completion. The progress bar is visually centered, and the center text provides a clear indication of the current progress toward the goal.

flutter_circular_percent_indicator_progress_bar

The CircularPercentIndicator widget also comes with quite a lot of properties, click here for the list.

  1. addAutomaticKeepAlive: Whether to add automatic keep alive to the circular progress indicator. (Type: bool)
  2. animateFromLastPercent: Whether to animate from the last percentage value or start from 0%. (Type: bool)
  3. animation: Whether to animate the circular progress indicator. (Type: bool)
  4. animationDuration: The duration of the animation. (Type: Duration)
  5. arcBackgroundColor: The color of the background when the arcType property is set to true. (Type: Color)
  6. arcType: By setting the arcType you can change the appearance of the circular progress indicator. (Type: ArcType)
  7. backgroundColor: The color of the unfilled progress of the circular progress indicator. (Type: Color)
  8. backgroundWidth: Width of the unfilled background of the circular progress indicator. (Type: double)
  9. center: A widget to display in the center of the circular progress indicator. (Type: Widget)
  10. circularStrokeCap: The shape of the circular progress indicator ends. Can be butt, round, or square. (Type: CircularStrokeCap)
  11. curve: Set a linear curve animation type. (Type: Curve)
  12. fillColor: The color of the whole background, the default is transparent. (Type: Color)
  13. footer: A widget to display below the circular progress indicator. (Type: Widget)
  14. header: A widget to display above the circular progress indicator. (Type: Widget)
  15. linearGradient: A gradient to apply to the circular progress indicator. (Type: LinearGradient)
  16. maskFilter: Creates a mask filter that takes the progress shape being drawn and blurs it. (Type: MaskFilter)
  17. onAnimationEnd: A callback function that is called when the animation completes. (Type: VoidCallback)
  18. padding: The padding around the circular progress indicator. (Type: EdgeInsets)
  19. percent: The percentage value to show in the circular progress indicator. (Type: double)
  20. progressColor: The color of the circular progress indicator. (Type: Color)
  21. radius: The radius of the circular progress indicator. (Type: double)
  22. restartAnimation: Restarts the animation when the value reaches 1.0. (Type: bool)
  23. reverse: Whether to reverse the direction of the progress indicator. (Type: bool)
  24. rotateLinearGradient: Whether to rotate the linear gradient colors. (Type: bool)
  25. startAngle: The starting angle (in degrees) of the circular progress indicator. (Type: double)
  26. widgetIndicator: A custom widget indicator to use instead of the default line. (Type: Widget)

Illustrating a Practical Use Case

In this section, we will look at a practical example that shows how to use progress bars in Flutter to make a step counter. When users open the page, the progress bar will show their current step count with animations, making it enjoyable and visually attractive.

import 'package:countup/countup.dart';
import 'package:flutter/material.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Progress bar demo'),
        ),
        body: Center(
          child: CircularPercentIndicator(
            animation: true,
            animationDuration: 1200,
            arcBackgroundColor: Colors.blue,
            arcType: ArcType.FULL,
            center: Countup(
              begin: 0,
              duration: Duration(milliseconds: 1200),
              end: 4326,
              style: TextStyle(fontSize: 30),
            ),
            footer: Text('Steps taken', style: TextStyle(fontSize: 30)),
            header: Padding(
              padding: const EdgeInsets.only(bottom: 20),
              child: Text('Goal: 6000', style: TextStyle(fontSize: 30)),
            ),
            lineWidth: 30.0,
            percent: 4326 / 6000,
            progressColor: Colors.green,
            radius: 100,
          ),
        ),
      ),
    );
  }
}

In this code snippet, we are using the CircularPercentIndicator widget. The progress indicator is animated (animation: true) with an animation duration of 1200 milliseconds (animationDuration: 1200). The unfilled line is blue (arcBackgroundColor: Colors.blue) and an arc of the circle is cut out (arcType: ArcType.FULL).

In the center of the circular progress indicator, there is a Countup widget that animates the number from 0 to 4326 within 1200 milliseconds. The number 4326 represents the steps taken toward the goal, and it is styled with a font size of 30.

The Countup widget is from the countup package, to install the package execute the following command: flutter pub add countup. It is a very convenient package to create animated numbers.

At the bottom of the circular progress indicator, there is a text widget displaying "Steps taken" with a font size of 30, acting as a footer. At the top of the circular progress indicator, there is another Text widget showing "Goal: 6000" with a font size of 30, serving as a header.

The width of the circular progress indicator line is set to 30.0 (lineWidth: 30.0). The completion percentage of the circular progress indicator is calculated as 4326 divided by 6000 (percent: 4326 / 6000), and the progress bar is colored green (progressColor: Colors.green).

The circular progress indicator has a radius of 100 (radius: 100).

When you run the application, the progress bar and progress number will start moving upward as soon as the page is ready.

flutter_circular_percent_indicator_showing_daily_steps

Conclusion

Flutter's percent_indicator package provides a straightforward and flexible way to create and customize progress bars for your Flutter applications. With the LinearPercentIndicator and CircularPercentIndicator widgets, you can effectively showcase progress and completion in both linear and circular formats.

Tags