π₯#10FlutterChallenges - Part 1: progress bar with gradient
Real scenarios & real problems. Learn how to make an custom progress bar with the gradient background that will looks tasty!
Series Intro π
Welcome to the #10FlutterChallenges series, where I'll show you how to build some real features built in Flutter.
In this series of blog posts, I show you 10 features with the tricky parts and a code solution build from scratch.
So let's get started!
Part 1:
In this part we want to build a simple progress bar that has a label that will display the current value and the maximum value after /
like that: 100/1000.
Issue #1 β progress bar
In order for this to work, we are going to need the following widgets provided by Flutter:
Below I prepared a ready code for the progress bar based on the above classes and adding a bit of style:
import 'package:flutter/material.dart';
class CustomProgressBar extends StatelessWidget {
const CustomProgressBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width,
height: 20,
child: const LinearProgressIndicator(
backgroundColor: Color(0xff323232),
valueColor: AlwaysStoppedAnimation<Color>(
Color(0xFF21bf73),
),
value: 0.5,
),
),
const Positioned.fill(
child: Align(
alignment: Alignment.center,
child: Text(
'200/1000',
style: TextStyle(
color: Colors.white,
fontSize: 10,
fontFamily: 'RetroGaming',
fontWeight: FontWeight.bold,
),
),
),
)
],
);
}
}
NOTE: It is important to pass value as a double integer in the range 0 - 1. The LinearProgressIndicator takes this value and it is converted as a percentage of the progress e.g. 0.2 = 20%.
Remember: you need to wrap the progress bar in Expanded class where you invoke it to prevent RenderBox exception.
As you have probably noticed, many values ββcan be passed from outside as arguments to this widget, e.g., colors, height etc. I encourage you to make it more general.
Okay, our progress bar looks fine, let's move on to the slightly more difficult part.
Issue #2 β candy cane π
Do you know how a candy cane looks like? If not, here's the picture:
Yes, I know it tastes great too π, but it's not a culinary blog. The point is, we want the background of the progress bar to look like the texture of this candy.
Step 1: Create background
First, we need to replace the previously created SizedBox
inside the Stack
with a Container
with additional styles. That will be our background bar where we will put the gradient:
Container(
width: MediaQuery.of(context).size.width,
height: 20,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey.shade200,
),
color: Colors.white70,
),
),
Step 2: Add gradient
The next thing to do is simply add another Container
over the current one. We can achieve this thanks to the Stack
widget. To do this, we need to add this new Container
after the first one:
Container(
width: MediaQuery.of(context).size.width - 100,
height: 20,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment(-0.75, -1.1),
end: Alignment(-0.6, 0),
stops: [0.0, 0.5, 0.5, 1],
colors: [
Colors.red,
Colors.red,
Colors.white,
Colors.white,
],
tileMode: TileMode.mirror,
),
),
),
Let's describe the important parts of this code:
- The Width factor is, for simplicity, reduced by
100
from the full width of the device (this should be replaced with some dynamic value such as%
) - Next comes the
LinearGradient
class, in which we define properties suited to our needs, such as steps, alignments, and colors array - The last thing is the
tileMode
property which is responsible for:
How this gradient should tile the plane beyond in the region before [begin] and after [end].
And the value of the mirror
will be just right to create our candy-cane gradient
SUMMARY:
That's it π Our candy-cane progress bar looks delicious. The label may remain unchanged. You can always check out the full source code below:

Whatβs next?
And that's all for this challenge βοΈ
In this post, I went over the build and customized progress bar using the built-in Flutter widgets and showed some customization possibilities.
In the next, we will build a toggle button, also with no external libraries.
Thanks for reading β₯οΈβ₯οΈ
β¦and stay tuned! π
Also check out the rest of the Flutter Challenges:
Part 1 β #10FlutterChallenges - Part 1: progress bar with gradient
Part 2 β #10FlutterChallenges - Part 2: switch button
Part 3 β #10FlutterChallenges - Part 3: Audio + LifeCycle service