LinearProgressIndicator class
A Material Design linear progress indicator, also known as a progress bar.
Learn more about LinearProgressIndicator on the Flutter YouTube channel.
A widget that shows progress along a line. There are two kinds of linear progress indicators:
- Determinate. Determinate progress indicators have a specific value at each point in time, and the value should increase monotonically from 0.0 to 1.0, at which time the indicator is complete. To create a determinate progress indicator, use a non-null value between 0.0 and 1.0.
- Indeterminate. Indeterminate progress indicators do not have a specific value at each point in time and instead indicate that progress is being made without indicating how much progress remains. To create an indeterminate progress indicator, use a null value.
The indicator line is displayed with valueColor, an animated value. To
specify a constant color value use: AlwaysStoppedAnimation<Color>(color).
The minimum height of the indicator can be specified using minHeight. The indicator can be made taller by wrapping the widget with a SizedBox.
This example showcases determinate and indeterminate LinearProgressIndicators.
The LinearProgressIndicators will use the
when setting the LinearProgressIndicator.year2023 flag to false.
To see it in action, copy and run this code snippet on DartPad.
import 'package:material_ui/material_ui.dart';
/// Flutter code sample for [LinearProgressIndicator].
void main() => runApp(const ProgressIndicatorExampleApp());
class ProgressIndicatorExampleApp extends StatelessWidget {
const ProgressIndicatorExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(home: ProgressIndicatorExample());
}
}
class ProgressIndicatorExample extends StatefulWidget {
const ProgressIndicatorExample({super.key});
@override
State<ProgressIndicatorExample> createState() =>
_ProgressIndicatorExampleState();
}
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
with TickerProviderStateMixin {
late AnimationController controller;
bool year2023 = true;
@override
void initState() {
super.initState();
controller =
AnimationController(
/// [AnimationController]s can be created with `vsync: this` because of
/// [TickerProviderStateMixin].
vsync: this,
duration: const Duration(seconds: 5),
)
..addListener(() {
setState(() {});
})
..repeat(reverse: true);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
spacing: 16.0,
mainAxisAlignment: .center,
children: <Widget>[
const Text('Determinate LinearProgressIndicator'),
Padding(
padding: const .symmetric(horizontal: 16),
child: LinearProgressIndicator(
// ignore: deprecated_member_use
year2023: year2023,
value: controller.value,
),
),
const Text('Indeterminate LinearProgressIndicator'),
Padding(
padding: const .symmetric(horizontal: 16),
// ignore: deprecated_member_use
child: LinearProgressIndicator(year2023: year2023),
),
SwitchListTile(
value: year2023,
title: year2023
? const Text('Switch to latest M3 style')
: const Text('Switch to year2023 M3 style'),
onChanged: (bool value) {
setState(() {
year2023 = !year2023;
});
},
),
],
),
);
}
}
This sample shows the creation of a LinearProgressIndicator with a changing value. When toggling the switch, LinearProgressIndicator uses a determinate value. As described in: https://m3.material.io/components/progress-indicators/overview
To see it in action, copy and run this code snippet on DartPad.
import 'package:material_ui/material_ui.dart';
/// Flutter code sample for [LinearProgressIndicator].
void main() => runApp(const ProgressIndicatorExampleApp());
class ProgressIndicatorExampleApp extends StatelessWidget {
const ProgressIndicatorExampleApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(home: ProgressIndicatorExample());
}
}
class ProgressIndicatorExample extends StatefulWidget {
const ProgressIndicatorExample({super.key});
@override
State<ProgressIndicatorExample> createState() =>
_ProgressIndicatorExampleState();
}
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
with TickerProviderStateMixin {
late AnimationController controller;
bool determinate = false;
@override
void initState() {
super.initState();
controller =
AnimationController(
/// [AnimationController]s can be created with `vsync: this` because of
/// [TickerProviderStateMixin].
vsync: this,
duration: const Duration(seconds: 2),
)
..addListener(() {
setState(() {});
})
..repeat(reverse: true);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const .all(20.0),
child: Column(
spacing: 16.0,
mainAxisAlignment: .center,
children: <Widget>[
const Text(
'Linear progress indicator',
style: TextStyle(fontSize: 20),
),
LinearProgressIndicator(
value: determinate ? controller.value : null,
semanticsLabel: 'Linear progress indicator',
),
Row(
children: <Widget>[
Expanded(
child: Text(
'${determinate ? 'Determinate' : 'Indeterminate'} Mode',
style: Theme.of(context).textTheme.titleSmall,
),
),
Switch(
value: determinate,
onChanged: (bool value) {
setState(() {
determinate = value;
if (determinate) {
controller.stop();
} else {
controller
..forward(from: controller.value)
..repeat();
}
});
},
),
],
),
],
),
),
);
}
}
Animation synchronization
When multiple CircularProgressIndicators or LinearProgressIndicators are animating on screen simultaneously (e.g., in a list of loading items), their uncoordinated animations can appear visually cluttered. To address this, the animation of an indicator can be driven by a custom AnimationController.
This allows multiple indicators to be synchronized to a single animation source. The most convenient way to achieve this for a group of indicators is by providing a controller via ProgressIndicatorTheme (see ProgressIndicatorThemeData.controller). All CircularProgressIndicators or LinearProgressIndicators within that theme's subtree will then share the same animation, resulting in a more coordinated and visually pleasing effect.
Alternatively, a specific AnimationController can be passed directly to the controller property of an individual indicator.
See the documentation of CircularProgressIndicator for an example on this topic.
See also:
- CircularProgressIndicator, which shows progress along a circular arc.
- RefreshIndicator, which automatically displays a CircularProgressIndicator when the underlying vertical scrollable is overscrolled.
- material.io/design/components/progress-indicators.html#linear-progress-indicators
- Inheritance
-
- Object
- DiagnosticableTree
- Widget
- StatefulWidget
- ProgressIndicator
- LinearProgressIndicator
Constructors
-
LinearProgressIndicator({Key? key, double? value, Color? backgroundColor, Color? color, Animation<
Color?> ? valueColor, double? minHeight, String? semanticsLabel, String? semanticsValue, BorderRadiusGeometry? borderRadius, Color? stopIndicatorColor, double? stopIndicatorRadius, double? trackGap, @Deprecated('Set this flag to false to opt into the 2024 progress indicator appearance. Defaults to true. ' 'In the future, this flag will default to false. Use ProgressIndicatorThemeData to customize individual properties. ' 'This feature was deprecated after v3.26.0-0.1.pre.') bool? year2023, AnimationController? controller}) -
Creates a linear progress indicator.
const
Properties
- backgroundColor → Color?
-
Color of the track being filled by the linear indicator.
no setteroverride
- borderRadius → BorderRadiusGeometry?
-
The border radius of both the indicator and the track.
final
- color → Color?
-
The progress indicator's color.
finalinherited
- controller → AnimationController?
-
An optional AnimationController that controls the animation of this
indeterminate progress indicator.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- key → Key?
-
Controls how one widget replaces another widget in the tree.
finalinherited
- minHeight → double?
-
The minimum height of the line used to draw the linear indicator.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- semanticsLabel → String?
-
The SemanticsProperties.label for this progress indicator.
finalinherited
- semanticsValue → String?
-
The SemanticsProperties.value for this progress indicator.
finalinherited
- stopIndicatorColor → Color?
-
The color of the stop indicator.
final
- stopIndicatorRadius → double?
-
The radius of the stop indicator.
final
- trackGap → double?
-
The gap between the indicator and the track.
final
- value → double?
-
If non-null, the value of this progress indicator.
finalinherited
-
valueColor
→ Animation<
Color?> ? -
The progress indicator's color as an animated value.
finalinherited
- year2023 → bool?
-
When true, the LinearProgressIndicator will use the 2023 Material Design 3
appearance.
final
Methods
-
createElement(
) → StatefulElement -
Creates a StatefulElement to manage this widget's location in the tree.
inherited
-
createState(
) → State< LinearProgressIndicator> -
Creates the mutable state for this widget at a given location in the tree.
override
-
debugDescribeChildren(
) → List< DiagnosticsNode> -
Returns a list of DiagnosticsNode objects describing this node's
children.
inherited
-
debugFillProperties(
DiagnosticPropertiesBuilder properties) → void -
Add additional properties associated with the node.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toDiagnosticsNode(
{String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode -
Returns a debug representation of the object that is used by debugging
tools and by DiagnosticsNode.toStringDeep.
inherited
-
toString(
{DiagnosticLevel minLevel = DiagnosticLevel.info}) → String -
A string representation of this object.
inherited
-
toStringDeep(
{String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) → String -
Returns a string representation of this node and its descendants.
inherited
-
toStringShallow(
{String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String -
Returns a one-line detailed description of the object.
inherited
-
toStringShort(
) → String -
A short, textual description of this widget.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Constants
- defaultAnimationDuration → const Duration
- The default duration for one full cycle of the indeterminate animation.