top of page
Search
leemanuela94

Download Progress Bar Flutter: How to Track and Display the Download Status of a File



How to Show Download Progress in a Flutter App




A download progress indicator is a widget that shows how much of a file has been downloaded from a server. It is useful for providing feedback to the user and preventing them from thinking that your app is broken or frozen. In this article, you will learn how to show download progress in a Flutter app using different types of progress indicators.




download progress bar flutter




Flutter comes with two built-in progress indicator widgets: CircularProgressIndicator and LinearProgressIndicator. They are both part of the material library and follow the Material Design guidelines. You can also use a third-party package called percent_indicator that offers more customization options and features.


How to Use CircularProgressIndicator




A CircularProgressIndicator is a widget that shows progress along a circle. It can be either determinate or indeterminate, depending on whether you provide a value between 0.0 and 1.0 or not. A determinate progress indicator shows the actual percentage of completion, while an indeterminate one shows that something is happening without indicating how much is left.


In this section, you will learn how to use a CircularProgressIndicator to show the download progress of a file. You will need to do the following steps:


  • Add a progress indicator to your UI layout



  • Add a button to start downloading a file



  • Implement the download logic using Dio package



  • Update the progress value using ValueNotifier



Add a progress indicator to your UI layout




The first step is to add a CircularProgressIndicator widget to your UI layout. You can use a SizedBox widget to specify the size of the indicator, and a ValueListenableBuilder widget to update it based on the value of a ValueNotifier. Here is an example:


child: SizedBox( width: 100, height: 100, child: ValueListenableBuilder( valueListenable: manager.progressNotifier, builder: (context, percent, child) return CircularProgressIndicator( strokeWidth: 20, value: percent, // This parameter is what makes it a determinate progress indicator, // that is, it's what makes the indicator show the portion that's completed. // Without it (or when null), it becomes an indeterminate progress indicator // and just keeps spinning forever. // The value should be a double between 0.0 and 1.0. // If it goes above 1.0 then it will just show a full circle like null does. ); , ), ),


The value parameter is what makes it a determinate progress indicator, that is, it's what makes the indicator show the portion that's completed. Without it (or when null), it becomes an indeterminate progress indicator and just keeps spinning forever. The value should be a double between 0.0 and 1.0. If it goes above 1.0 then it will just show a full circle like null does.


Notice that I am getting the download progress from manager.progressNotifier. I'm using a custom class called DownloadManager that handles the download logic and notifies the UI about the progress. I will explain how to implement this class later.


How to show download progress in a Flutter app


Create a download button with CircularProgressIndicator in Flutter


LinearProgressIndicator class - material library - Dart API


Flutter download file with progress bar example


How to use Dio to download files with progress in Flutter


Flutter custom progress indicator widget tutorial


How to create a circular progress bar with percentage in Flutter


Download large files in chunks with pause and resume in Flutter


How to make a determinate and indeterminate progress indicator in Flutter


Flutter download manager with progress indicator and resume support


How to implement a file downloader with a progress bar using Flutter and Firebase


How to create a beautiful download animation in Flutter


How to use flutter_downloader plugin to download files in Flutter


How to show a snackbar with a progress indicator in Flutter


How to create a horizontal progress bar with custom colors in Flutter


How to use StreamBuilder to update the progress of a download task in Flutter


How to create a radial progress bar with gradient colors in Flutter


How to download multiple files concurrently with progress in Flutter


How to use flutter_progress_dialog package to show a progress dialog in Flutter


How to create a custom shaped progress bar in Flutter


How to use flutter_easyloading package to show loading and progress indicators in Flutter


How to create a countdown timer with a progress bar in Flutter


How to use flutter_progress_button package to create animated buttons with progress indicators in Flutter


How to create a liquid progress indicator in Flutter


How to use flutter_file_manager package to manage downloaded files in Flutter


How to create a step progress indicator in Flutter


How to use flutter_spinkit package to show animated loading indicators in Flutter


How to create a wave progress indicator in Flutter


How to use flutter_downloader_ui package to show a download list with progress indicators in Flutter


How to create a heart beat animation with a progress bar in Flutter


How to use http package to download files with headers and parameters in Flutter


How to create a circular slider with a progress bar in Flutter


How to use flutter_progress_hud package to show a HUD with loading and progress indicators in Flutter


How to create a flip card animation with a progress bar in Flutter


How to use workmanager package to run background download tasks in Flutter


How to create a percentage circle with a progress bar in Flutter


How to use flutter_styled_toast package to show toast messages with progress indicators in Flutter


How to create a curved progress bar in Flutter


How to use flutter_archive package to zip and unzip downloaded files in Flutter


How to create a bouncing ball animation with a progress bar in Flutter


How to use dio_http_cache package to cache downloaded files in Flutter


How to create a snake game with a progress bar in Flutter


How to use flutter_statusbarcolor package to change the status bar color according to the progress value in Flutter


How to create a rotating cube animation with a progress bar in Flutter


How to use path_provider package to get the directory for saving downloaded files in Flutter


How to create a battery level indicator with a progress bar in Flutter


How to use permission_handler package to request storage permission for downloading files in Flutter


How to create a music player UI with a progress bar in Flutter


How to use flutter_local_notifications package to show notifications for download status in Flutter


Add a button to start downloading a file




The next step is to add a button to start downloading a file. You can use a FloatingActionButton widget and attach an onPressed callback to it. Here is an example:


floatingActionButton: FloatingActionButton( child: Icon(Icons.download), onPressed: () // Call the download method of the DownloadManager manager.download(); , ),


The onPressed callback calls the download method of the DownloadManager class, which will start the download process and update the progress value. I will explain how to implement this method later.


Implement the download logic using Dio package




The third step is to implement the download logic using Dio package. Dio is a powerful HTTP client for Flutter that supports features like interceptors, global configuration, form data, request cancellation, file downloading, etc. You can install it by adding this line to your pubspec.yaml file:


dependencies: dio: ^4.0.4


Then, you can import it in your code like this:


import 'package:dio/dio.dart';


To download a file using Dio, you need to create an instance of Dio class and call its download method. The method takes three parameters: the URL of the file, the path where to save the file, and an optional onReceiveProgress callback that reports the download progress. Here is an example:


class DownloadManager // Create a Dio instance final dio = Dio(); // Define the URL of the file to download final url = ' // Define the path where to save the file final path = '/storage/emulated/0/Download/file.zip'; // Define a ValueNotifier to store and notify the progress value final progressNotifier = ValueNotifier(null); // Define a method to start downloading the file Future download() async try // Call the download method of Dio await dio.download( url, path, onReceiveProgress: (received, total) // Calculate the percentage of completion double percent = received / total; // Update the progress value using ValueNotifier progressNotifier.value = percent; , ); catch (e) // Handle any errors or exceptions print(e);


The onReceiveProgress callback receives two parameters: received and total, which are the number of bytes received and the total number of bytes of the file, respectively. You can calculate the percentage of completion by dividing them and assign it to the progressNotifier.value. This will trigger the ValueListenableBuilder widget in your UI layout to update the CircularProgressIndicator.


Update the progress value using ValueNotifier




The last step is to update the progress value using ValueNotifier. A ValueNotifier is a simple way to provide state changes to widgets that depend on them. It holds a single value and notifies its listeners when the value changes. You can create a ValueNotifier by passing an initial value to its constructor, and update its value by assigning a new value to its value property.


In this case, I have created a ValueNotifier called progressNotifier in my DownloadManager class and initialized it with null. This means that the progress indicator will start as an indeterminate one until the download starts. Then, I update its value with the percentage of completion in the onReceiveProgress callback of the dio.download method. This means that the progress indicator will show the actual progress of the download until it reaches 100%. You can also add some logic to handle the completion or cancellation of the download, such as showing a toast message or resetting the progress value to null.


How to Use LinearProgressIndicator




A LinearProgressIndicator is a widget that shows progress along a horizontal line. It can also be either determinate or indeterminate, depending on whether you provide a value between 0.0 and 1.0 or not. A determinate progress indicator shows the actual percentage of completion, while an indeterminate one shows that something is happening without indicating how much is left.


In this section, you will learn how to use a LinearProgressIndicator instead of a CircularProgressIndicator to show the download progress of a file. You will need to do the following steps:


  • Replace CircularProgressIndicator with LinearProgressIndicator



  • Adjust the height and width of the indicator



Replace CircularProgressIndicator with LinearProgressIndicator




The first step is to replace CircularProgressIndicator with LinearProgressIndicator. You can simply change the widget name and keep the same parameters. Here is an example:


child: ValueListenableBuilder( valueListenable: manager.progressNotifier, builder: (context, percent, child) return LinearProgressIndicator( value: percent, // This parameter is what makes it a determinate progress indicator, // that is, it's what makes the indicator show the portion that's completed. // Without it (or when null), it becomes an indeterminate progress indicator // and just keeps moving back and forth. // The value should be a double between 0.0 and 1.0. // If it goes above 1.0 then it will just show a full line like null does. ); , ),


The value parameter is what makes it a determinate progress indicator, that is, it's what makes the indicator show the portion that's completed. Without it (or when null), it becomes an indeterminate progress indicator and just keeps moving back and forth. The value should be a double between 0.0 and 1.0. If it goes above 1.0 then it will just show a full line like null does.


Adjust the height and width of the indicator




The second step is to adjust the height and width of the indicator. Unlike CircularProgressIndicator, which has a fixed size, LinearProgressIndicator takes up all the available space in its parent widget. You can use a SizedBox, a Padding, or any other widget that can control the size and position of its child widget to adjust the height and width of the indicator. Here is an example:


child: SizedBox( height: 20, width: 300, child: ValueListenableBuilder( valueListenable: manager.progressNotifier, builder: (context, percent, child) return LinearProgressIndicator( value: percent, ); , ), ),


This will make the indicator have a height of 20 pixels and a width of 300 pixels. You can change these values according to your preference and design.


How to Use Percent Indicator Package




A third option to show download progress in a Flutter app is to use a third-party package called percent_indicator. This package provides two widgets: LinearPercentIndicator and CircularPercentIndicator, which are similar to Flutter's built-in progress indicators but offer more customization options and features.


In this section, you will learn how to use this package to show download progress in a Flutter app. You will need to do the following steps:


  • Install the package and import it in your code



  • Use LinearPercentIndicator or CircularPercentIndicator widgets



  • Customize the appearance and behavior of the indicators



Install the package and import it in your code




The first step is to install the percent_indicator package and import it in your code. You can install it by adding this line to your pubspec.yaml file:


dependencies: percent_indicator: ^3.4.0


Then, you can import it in your code like this:


import 'package:percent_indicator/percent_indicator.dart';


Use LinearPercentIndicator or CircularPercentIndicator widgets




The second step is to use LinearPercentIndicator or CircularPercentIndicator widgets instead of Flutter's built-in progress indicators. These widgets have similar parameters as Flutter's progress indicators, such as value, strokeWidth, etc., but also have some additional parameters, such as animation, center, progressColor, etc. Here are some examples:


child: LinearPercentIndicator( width: 300, lineHeight: 20, percent: percent ?? 0, // This parameter is what makes it a determinate progress indicator, // that is, it's what makes the indicator show the portion that's completed. // The value should be a double between 0.0 and 1.0. // If it goes above 1.0 then it will just show a full line like null does. animation: true, // This parameter is what makes the indicator animate from zero to the current value. // The default value is false. animationDuration: 1000, // This parameter is what controls the duration of the animation in milliseconds. // The default value is 500. center: Text('$(percent ?? 0) * 100%'), // This parameter is what allows you to show a widget in the center of the indicator. // You can use any widget you want, such as a text, an icon, an image, etc. progressColor: Colors.green, // This parameter is what allows you to change the color of the indicator. ),


child: CircularPercentIndicator( radius: 100, lineWidth: 20, percent: percent ?? 0, // This parameter is what makes it a determinate progress indicator, // that is, it's what makes the indicator show the portion that's completed. // The value should be a double between 0.0 and 1.0. // If it goes above 1.0 then it will just show a full circle like null does. animation: true, // This parameter is what makes the indicator animate from zero to the current value. // The default value is false. animationDuration: 1000, // This parameter is what controls the duration of the animation in milliseconds. // The default value is 500. center: Text('$(percent ?? 0) * 100%'), // This parameter is what allows you to show a widget in the center of the indicator. // You can use any widget you want, such as a text, an icon, an image, etc. progressColor: Colors.green, // This parameter is what allows you to change the color of the indicator. ),


Customize the appearance and behavior of the indicators




The third step is to customize the appearance and behavior of the indicators. The percent_indicator package offers many parameters that you can use to change the look and feel of the indicators. For example, you can use backgroundColor to change the color of the background, linearStrokeCap or circularStrokeCap to change the shape of the ends of the indicator, maskFilter to add a blur effect, reverse to change the direction of the indicator, etc. You can also use addAutomaticKeepAlive to keep the indicator alive even when it is not visible on the screen, or restartAnimation to restart the animation when the value changes. Here are some examples:


child: LinearPercentIndicator( width: 300, lineHeight: 20, percent: percent ?? 0, animation: true, animationDuration: 1000, center: Text('$(percent ?? 0) * 100%'), progressColor: Colors.green, backgroundColor: Colors.grey, // This parameter is what allows you to change the color of the background. linearStrokeCap: LinearStrokeCap.roundAll, // This parameter is what allows you to change the shape of the ends of the indicator. // The possible values are LinearStrokeCap.butt, LinearStrokeCap.round, LinearStrokeCap.roundAll. maskFilter: MaskFilter.blur(BlurStyle.solid, 3), // This parameter is what allows you to add a blur effect to the indicator. ),


child: CircularPercentIndicator( radius: 100, lineWidth: 20, percent: percent ?? 0, animation: true, animationDuration: 1000, center: Text('$(percent ?? 0) * 100%'), progressColor: Colors.green, backgroundColor: Colors.grey, // This parameter is what allows you to change the color of the background. circularStrokeCap: CircularStrokeCap.round, // This parameter is what allows you to change the shape of the ends of the indicator. // The possible values are CircularStrokeCap.butt, CircularStrokeCap.round, CircularStrokeCap.square. reverse: true, // This parameter is what allows you to change the direction of the indicator. // The default value is false, which means the indicator starts from the top and goes clockwise. // If true, the indicator starts from the bottom and goes counterclockwise. ),


For more details and examples, you can check the of the percent_indicator package.


Conclusion




In this article, you have learned how to show download progress in a Flutter app using different types of progress indicators. You have seen how to use Flutter's built-in CircularProgressIndicator and LinearProgressIndicator, as well as a third-party package called percent_indicator. You have also learned how to implement the download logic using Dio package and how to update the progress value using ValueNotifier.


Showing download progress is a common feature in many apps, and it can improve the user experience and satisfaction. By using the techniques and widgets discussed in this article, you can easily add this feature to your Flutter app and customize it according to your needs and preferences.


Here are some tips and resources for further learning:


  • Use package if you want to download files in the background and handle more complex scenarios.



  • Use package if you want to show a progress dialog with a message and a cancel button.



  • Use package if you want to use more fancy and animated progress indicators.



  • Check out for more tips on how to improve your Flutter app performance.



  • Check out for more tips on how to improve your Flutter app design.



Frequently Asked Questions




How do I change the color of the progress indicator?




You can change the color of the progress indicator by using the progressColor parameter. For example:


CircularProgressIndicator( value: percent, progressColor: Colors.red, ),


This will make the indicator red. You can use any color you want, such as Colors.blue, Colors.green, etc. You can also use Color.fromRGBO(), Color.fromARGB(), or Color.fromRGBO() methods to create custom colors.


How do I show a text or an icon in the center of the progress indicator?




You can show a text or an icon in the center of the progress indicator by using the center parameter. For example:


CircularProgressIndicator( value: percent, center: Text('Downloading...'), ),


This will show a text saying 'Downloading...' in the center of the indicator. You can use any widget you want, such as an icon, an image, etc. For example:


CircularProgressIndicator( value: percent, center: Icon(Icons.file_download), ),


This will show an icon of a file download in the center of the indicator.


How do I make the progress indicator animate from zero to the current value?




You can make the progress indicator animate from zero to the current value by using the animation parameter. For example:


CircularProgressIndicator( value: percent, animation: true, ),


This will make the indicator animate from zero to the current value. The default value of the animation parameter is false, which means the indicator will jump to the current value without animation. You can also use the animationDuration parameter to control the duration of the animation in milliseconds. The default value is 500.


How do I use a custom widget as a progress indicator?




You can use a custom widget as a progress indicator by using the CustomPaint widget and implementing your own CustomPainter class. The CustomPaint widget allows you to draw anything you want on a canvas, and the CustomPainter class defines how to paint it. You can use the paint method of the CustomPainter class to draw shapes, paths, texts, images, etc. using the Canvas and Paint objects. You can also use the shouldRepaint method of the CustomPainter class to determine when to repaint the widget based on the progress value. Here is an example:


class CustomProgressIndicator extends StatelessWidget final double? percent; CustomProgressIndicator(this.percent); @override Widget build(BuildContext context) return CustomPaint( painter: CustomProgressPainter(percent), size: Size(100, 100), ); class CustomProgressPainter extends CustomPainter final double? percent; CustomProgressPainter(this.percent); @override void paint(Canvas canvas, Size size) // Create a Paint object Paint paint = Paint() ..color = Colors.blue ..strokeWidth = 10 ..style = PaintingStyle.stroke; // Draw a circle canvas.drawCircle( Offset(size.width / 2, size.height / 2), // Center point size.width / 2 - paint.strokeWidth / 2, // Radius paint, ); // Draw an arc canvas.drawArc( Rect.fromCircle( center: Offset(size.width / 2, size.height / 2), // Center point radius: size.width / 2 - paint.strokeWidth / 2, // Radius ), -pi / 2, // Start angle percent! * 2 * pi, // Sweep angle false, // Use center paint..color = Colors.green, // Change color ); @override bool shouldRepaint(covariant CustomProgressPainter oldDelegate) return oldDelegate.percent != percent;


This will create a custom progress indicator that looks like this:



You can customize it however you want by changing the parameters and drawing methods.


How do I show download progress in a list view or a grid view?




You can show download progress in a list view or a grid view by using the same widgets and techniques discussed in this article, but inside a ListTile, a Card, or any other widget that can display multiple items in a scrollable layout. You can also use a ListBuilder, a GridView.builder, or any other widget that can create items dynamically based on data. Here is an example:


child: ListView.builder( itemCount: files.length, itemBuilder: (context, index) return ListTile( leading: Icon(Icons.file_download), title: Text(files[index].name), trailing: SizedBox( width: 100, child: ValueListenableBuilder( valueListenable: files[index].progressNotifier, builder: (context, percent, child) return LinearProgressIndicator( value: percent, ); , ), ), ); , ),


This will create a list view that shows download progress for each file like this:



You can customize it however you want by changing the widgets and parameters.





I hope you enjoyed this 44f88ac181


1 view0 comments

Recent Posts

See All

Comments


bottom of page