Flutter Progress Bar
A progress bar is a graphic user interface used for showing the progress of a task such as downloading, uploading, installation, file transfer, etc. In this section, we are going to learn how to show a progress bar in a flutter application.
Flutter displays progress bar with the help of two widgets, which are given below:
- LinearProgressIndicator
- CircularProgressIndicator
Let us understand it in detail.
LinearProgressIndicator
The linear progress bar is used for showing the progress as a horizontal line.
Flutter have two types of linear progress indicators:
- Determinate: Determinate progress bar is used to show the actual amount of progress being made in the task. Its increases from 0.0 to 1.0 to show the amount of completion in the task. We need to add the value between 0.0 and 1.0.
- Indeterminate: This does not indicate the amount of progress. It makes progress without showing how much progress is remaining.
Properties
The following are the most common properties of linear progress bar:
- double value: This specifies the non-null value between 0.0 to 1.0, representing the completion of the progress.
- Color backgroundColor: This specifies the background color of the widget.
- Animation<<Color> valueColor: This specifies the progress indicator’s color as an animated value.
Example
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: LinearProgressIndicatorApp(), ); } } class LinearProgressIndicatorApp extends StatefulWidget { @override StatecreateState() { return LinearProgressIndicatorAppState(); } } class LinearProgressIndicatorAppState extends State { bool _loading; @override void initState() { super.initState(); _loading = false; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Flutter Linear Progress Bar"), ), body: Center( child: Container( padding: EdgeInsets.all(12.0), child: _loading ? LinearProgressIndicator() : Text( "Press button for downloading", style: TextStyle(fontSize: 25)), ), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _loading = !_loading; }); }, tooltip: 'Download', child: Icon(Icons.cloud_download), ), ); } }
Output
Let’s make a determinate progress bar:
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: LinearProgressIndicatorApp(), ); } } class LinearProgressIndicatorApp extends StatefulWidget { @override StatecreateState() { return LinearProgressIndicatorAppState(); } } class LinearProgressIndicatorAppState extends State { bool _loading; double _progressValue; @override void initState() { super.initState(); _loading = false; _progressValue = 0.0; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Flutter Linear Progress Bar"), ), body: Center( child: Container( padding: EdgeInsets.all(12.0), child: _loading ? Column( mainAxisAlignment: MainAxisAlignment.center, children: [ LinearProgressIndicator( backgroundColor: Colors.cyanAccent, valueColor: new AlwaysStoppedAnimation (Colors.red), value: _progressValue, ), Text('${(_progressValue * 100).round()}%'), ], ) : Text("Press button for downloading", style: TextStyle(fontSize: 25)), ), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _loading = !_loading; _updateProgress(); }); }, tooltip: 'Download', child: Icon(Icons.cloud_download), ), ); } // this function updates the progress value void _updateProgress() { const oneSec = const Duration(seconds: 1); new Timer.periodic(oneSec, (Timer t) { setState(() { _progressValue += 0.1; // we "finish" downloading here if (_progressValue.toStringAsFixed(1) == '1.0') { _loading = false; t.cancel(); return; } }); }); } }
Output
CircularProgressIndicator
This is very similar to LinearProgressIndicator just instead of Horizontal line we add a circular progress.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Flutter Progress Bar Example'), ), body: Center( child: CircularProgressIndicatorApp() ), ), ); } } /// This is the stateless widget that the main application instantiates. class CircularProgressIndicatorApp extends StatelessWidget { @override Widget build(BuildContext context) { return CircularProgressIndicator( backgroundColor: Colors.red, strokeWidth: 8,); } }
Output
Deterministic Progress
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: CircularProgressIndicatorApp(), ); } } class CircularProgressIndicatorApp extends StatefulWidget { @override StatecreateState() { return CircularProgressIndicatorAppState(); } } class CircularProgressIndicatorAppState extends State { bool _loading; double _progressValue; @override void initState() { super.initState(); _loading = false; _progressValue = 0.0; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Flutter Circular Progress Bar"), ), body: Center( child: Container( padding: EdgeInsets.all(14.0), child: _loading ? Column( mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator( strokeWidth: 10, backgroundColor: Colors.yellow, valueColor: new AlwaysStoppedAnimation (Colors.red), value: _progressValue, ), Text('${(_progressValue * 100).round()}%'), ], ) : Text("Press button for downloading", style: TextStyle(fontSize: 25)), ), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _loading = !_loading; _updateProgress(); }); }, child: Icon(Icons.cloud_download), ), ); } // this function updates the progress value void _updateProgress() { const oneSec = const Duration(seconds: 1); new Timer.periodic(oneSec, (Timer t) { setState(() { _progressValue += 0.2; // we "finish" downloading here if (_progressValue.toStringAsFixed(1) == '1.0') { _loading = false; t.cancel(); return; } }); }); } }