#4 CircularProgressIndicator and LinearProgressIndicator(Flutter Famous Widgets’ Guide)

Programmers Pouch
4 min readDec 25, 2021

--

Hey everyone! This is the fourth article of the series, Flutter Famous Widgets’ Guide. If you haven’t yet checked the previous articles, then go right here: 1st, 2nd and 3rd. Let’s get started!

CircularProgressIndicator and LinearProgressIndicator

CircularProgressIndicator and LinearProgressIndicator, two topics for today. We’ll go through the basic concepts, and then check out some harder ones.

What are those?

CircularProgressIndicator is a material design circular progress indicator, which spins to indicate that the application is busy so that the user can hold on.

LinearProgressIndicator is a material design linear progress indicator, also known as a progress bar.

How to Make Them?

  1. Create a new Flutter project in your IDE(Any would work but I’m using Android Studio).
  2. Open the main.dart file. Make a new stful widget. Name it ProgressIndicatorDemo.
  3. Let’s first add some widgets on our screen. Add a Scaffold widget with a body of a Center widget.
  4. Set the Column widget as the child of the Center widget.
  5. Set the mainAxisAlignment and crossAxisAlignment to center.
  6. Now add some children to it. Let’s the widgets in need: CircularProgessIndicator and LinearProgressIndicator.
  7. Add some space between them by using SizedBox.
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(
height: 60,
),
LinearProgressIndicator(),
],
),
),
);
}

Done! A very simple and easy case.

Changing the Color

Now, let’s try and change the color of these indicators. We can achieve this by using the backGroundColor properties that applies to both of them.

CircularProgressIndicator(
backgroundColor: Colors.orangeAccent,
),
SizedBox(
height: 60,
),
LinearProgressIndicator(
backgroundColor: Colors.orangeAccent,
),

You must’ve noticed that it doesn’t change the color of the indicator completely. For that, we’ve to use the valueColor property.

CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
backgroundColor: Colors.orangeAccent,
),
SizedBox(
height: 60,
),
LinearProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
backgroundColor: Colors.orangeAccent,
),

This is how we do it!

Changing the Dimensions

Changing the dimensions is pretty easy. Wrapping them with a Container widget and provide it with height and width would do the work.

Container(
height: 60,
width: 60,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
backgroundColor: Colors.orangeAccent,
),
),
SizedBox(
height: 60,
),
Container(
height: 20,
width: 300,
child: LinearProgressIndicator(
backgroundColor: Colors.orangeAccent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
),
),

We can also change the width inside the indicator by using the stokeWidth property, which takes in a double(NOTE: Only for CircularProgressIndicator. You can remove the width property from the Container )

For LinearProgressIndicator, we can use the minHeight property, which takes in a double as well (NOTE: You can remove the heightwidget from the LinearProgressIndicator).

Container(
height: 40,
child: CircularProgressIndicator(
strokeWidth: 20,
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
backgroundColor: Colors.orangeAccent,
),
),
SizedBox(
height: 60,
),
Container(
height: 30,
child: LinearProgressIndicator(
minHeight: 20,
backgroundColor: Colors.orangeAccent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
),
),

Now, that itself doesn’t look like an indicator. But, let’s go on.

Controlling

Now let’s control our indicators by using AnimationController. We have to add with TickerProviderStateMixin(AnimationControllerscan be created with `vsync: this` because of TickerProviderStateMixin).

Let’s add the required variables.

class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> with TickerProviderStateMixin{
AnimationController controller;

Now, set the duration using the duration property. Also add vsync: this.

@override
void initState() {
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 8),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: false);
super.initState();
}

Don’t forget to diposeit.

@override
void dispose() {
controller.dispose();
super.dispose();
}

Now add controller.value in place of the value property of both the indicators.

value: controller.value,

Great work!

Complete Code

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

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(home: ProgressIndicatorDemo());
}
}

class ProgressIndicatorDemo extends StatefulWidget {
const ProgressIndicatorDemo({Key key}) : super(key: key);

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

class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo>
with TickerProviderStateMixin {
AnimationController controller;

@override
void initState() {
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 8),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: false);
super.initState();
}

@override
void dispose() {
controller.dispose();
super.dispose();
}

Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 45,
child: CircularProgressIndicator(
value: controller.value,
strokeWidth: 20,
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
backgroundColor: Colors.orangeAccent,
),
),
SizedBox(
height: 60,
),
Container(
width: 300,
child: LinearProgressIndicator(
value: controller.value,
minHeight: 20,
backgroundColor: Colors.orangeAccent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.greenAccent),
),
),
],
),
),
);
}
}

We are done🏁. Hope you enjoyed!

Make sure to hit the claps👏if you liked this article. If I got something wrong, mention it in the comments.

Buy me a coffee☕ to show me your support.

Reach me out at LinkedIn, GitHub and Twitter.

--

--