Update Material 3 CircularProgressIndicator
for new visual style (#158104)
Related [Update both `ProgressIndicator` for Material 3 redesign](https://github.com/flutter/flutter/issues/141340) Fixes [Issue: Cannot theme progress indicators, many properties missing](https://github.com/flutter/flutter/issues/131690) Fixes [Cannot override default `CircularProgressIndicator` size](https://github.com/flutter/flutter/issues/158106) ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( // progressIndicatorTheme: const ProgressIndicatorThemeData( // constraints: BoxConstraints.tightFor(width: 100, height: 100), // strokeWidth: 12 // ), ), home: Scaffold( appBar: AppBar(title: const Text('CircularProgressIndicator')), body: const Center( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ CircularProgressIndicator(year2023: false, value: 0.5), CircularProgressIndicator(year2023: false), ], ), ), ), ); } } ``` </details> ### Preview <img width="579" alt="Screenshot 2024-11-04 at 16 01 57" src="https://github.com/user-attachments/assets/d27768c6-5570-48d0-9eed-565e02be8041"> ### New custom `CircularProgressIndicator.constraints` and stroke width <img width="579" alt="Screenshot 2024-11-04 at 16 02 40" src="https://github.com/user-attachments/assets/c67c4a31-58f4-4f82-bfb6-f1b78a000bac"> ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
a1c7a0dda4
commit
1686fa7eb4
@ -12,16 +12,32 @@ class ProgressIndicatorTemplate extends TokenTemplate {
|
||||
@override
|
||||
String generate() => '''
|
||||
class _Circular${blockName}DefaultsM3 extends ProgressIndicatorThemeData {
|
||||
_Circular${blockName}DefaultsM3(this.context);
|
||||
_Circular${blockName}DefaultsM3(this.context, { required this.indeterminate });
|
||||
|
||||
final BuildContext context;
|
||||
late final ColorScheme _colors = Theme.of(context).colorScheme;
|
||||
final bool indeterminate;
|
||||
|
||||
@override
|
||||
Color get color => ${componentColor('md.comp.progress-indicator.active-indicator')};
|
||||
|
||||
@override
|
||||
Color get circularTrackColor => ${componentColor('md.comp.progress-indicator.track')};
|
||||
Color? get circularTrackColor => indeterminate ? null : ${componentColor('md.comp.progress-indicator.track')};
|
||||
|
||||
@override
|
||||
double get strokeWidth => ${getToken('md.comp.progress-indicator.track.thickness')};
|
||||
|
||||
@override
|
||||
double? get strokeAlign => CircularProgressIndicator.strokeAlignInside;
|
||||
|
||||
@override
|
||||
BoxConstraints get constraints => const BoxConstraints(
|
||||
minWidth: 48.0,
|
||||
minHeight: 48.0,
|
||||
);
|
||||
|
||||
@override
|
||||
double? get trackGap => ${getToken('md.comp.progress-indicator.active-indicator-track-space')};
|
||||
}
|
||||
|
||||
class _Linear${blockName}DefaultsM3 extends ProgressIndicatorThemeData {
|
||||
|
@ -17,7 +17,6 @@ import 'material.dart';
|
||||
import 'progress_indicator_theme.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
const double _kMinCircularProgressIndicatorSize = 36.0;
|
||||
const int _kIndeterminateLinearDuration = 1800;
|
||||
const int _kIndeterminateCircularDuration = 1333 * 2222;
|
||||
|
||||
@ -550,7 +549,7 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> with
|
||||
|
||||
class _CircularProgressIndicatorPainter extends CustomPainter {
|
||||
_CircularProgressIndicatorPainter({
|
||||
this.backgroundColor,
|
||||
this.trackColor,
|
||||
required this.valueColor,
|
||||
required this.value,
|
||||
required this.headValue,
|
||||
@ -560,6 +559,8 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
|
||||
required this.strokeWidth,
|
||||
required this.strokeAlign,
|
||||
this.strokeCap,
|
||||
this.trackGap,
|
||||
this.year2023 = true,
|
||||
}) : arcStart = value != null
|
||||
? _startAngle
|
||||
: _startAngle + tailValue * 3 / 2 * math.pi + rotationValue * math.pi * 2.0 + offsetValue * 0.5 * math.pi,
|
||||
@ -567,7 +568,7 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
|
||||
? clampDouble(value, 0.0, 1.0) * _sweep
|
||||
: math.max(headValue * 3 / 2 * math.pi - tailValue * 3 / 2 * math.pi, _epsilon);
|
||||
|
||||
final Color? backgroundColor;
|
||||
final Color? trackColor;
|
||||
final Color valueColor;
|
||||
final double? value;
|
||||
final double headValue;
|
||||
@ -579,6 +580,8 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
|
||||
final double arcStart;
|
||||
final double arcSweep;
|
||||
final StrokeCap? strokeCap;
|
||||
final double? trackGap;
|
||||
final bool year2023;
|
||||
|
||||
static const double _twoPi = math.pi * 2.0;
|
||||
static const double _epsilon = .001;
|
||||
@ -601,27 +604,57 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
|
||||
size.width - strokeOffset * 2,
|
||||
size.height - strokeOffset * 2,
|
||||
);
|
||||
final bool hasGap = trackGap != null && trackGap! > 0;
|
||||
|
||||
if (backgroundColor != null) {
|
||||
if (trackColor != null) {
|
||||
final Paint backgroundPaint = Paint()
|
||||
..color = backgroundColor!
|
||||
..color = trackColor!
|
||||
..strokeWidth = strokeWidth
|
||||
..strokeCap = strokeCap ?? StrokeCap.round
|
||||
..style = PaintingStyle.stroke;
|
||||
canvas.drawArc(
|
||||
arcBaseOffset & arcActualSize,
|
||||
0,
|
||||
_sweep,
|
||||
false,
|
||||
backgroundPaint,
|
||||
);
|
||||
// If hasGap is true, draw the background arc with a gap.
|
||||
if (hasGap && value! > _epsilon) {
|
||||
final double arcRadius = arcActualSize.shortestSide / 2;
|
||||
final double strokeRadius = strokeWidth / arcRadius;
|
||||
final double gapRadius = trackGap! / arcRadius;
|
||||
final double startGap = strokeRadius + gapRadius;
|
||||
final double endGap = value! < _epsilon ? startGap : startGap * 2;
|
||||
final double startSweep = (-math.pi / 2.0) + startGap;
|
||||
final double endSweep = math.max(0.0, _twoPi - clampDouble(value!, 0.0, 1.0) * _twoPi - endGap);
|
||||
// Flip the canvas for the background arc.
|
||||
canvas.save();
|
||||
canvas.scale(-1, 1);
|
||||
canvas.translate(-size.width, 0);
|
||||
canvas.drawArc(
|
||||
arcBaseOffset & arcActualSize,
|
||||
startSweep,
|
||||
endSweep,
|
||||
false,
|
||||
backgroundPaint,
|
||||
);
|
||||
// Restore the canvas to draw the foreground arc.
|
||||
canvas.restore();
|
||||
} else {
|
||||
canvas.drawArc(
|
||||
arcBaseOffset & arcActualSize,
|
||||
0,
|
||||
_sweep,
|
||||
false,
|
||||
backgroundPaint,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (value == null && strokeCap == null) {
|
||||
// Indeterminate
|
||||
paint.strokeCap = StrokeCap.square;
|
||||
if (year2023) {
|
||||
if (value == null && strokeCap == null) {
|
||||
// Indeterminate
|
||||
paint.strokeCap = StrokeCap.square;
|
||||
} else {
|
||||
// Butt when determinate (value != null) && strokeCap == null;
|
||||
paint.strokeCap = strokeCap ?? StrokeCap.butt;
|
||||
}
|
||||
} else {
|
||||
// Butt when determinate (value != null) && strokeCap == null;
|
||||
paint.strokeCap = strokeCap ?? StrokeCap.butt;
|
||||
paint.strokeCap = strokeCap ?? StrokeCap.round;
|
||||
}
|
||||
|
||||
canvas.drawArc(
|
||||
@ -635,7 +668,7 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
|
||||
|
||||
@override
|
||||
bool shouldRepaint(_CircularProgressIndicatorPainter oldPainter) {
|
||||
return oldPainter.backgroundColor != backgroundColor
|
||||
return oldPainter.trackColor != trackColor
|
||||
|| oldPainter.valueColor != valueColor
|
||||
|| oldPainter.value != value
|
||||
|| oldPainter.headValue != headValue
|
||||
@ -644,7 +677,9 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
|
||||
|| oldPainter.rotationValue != rotationValue
|
||||
|| oldPainter.strokeWidth != strokeWidth
|
||||
|| oldPainter.strokeAlign != strokeAlign
|
||||
|| oldPainter.strokeCap != strokeCap;
|
||||
|| oldPainter.strokeCap != strokeCap
|
||||
|| oldPainter.trackGap != trackGap
|
||||
|| oldPainter.year2023 != year2023;
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,19 +733,28 @@ class CircularProgressIndicator extends ProgressIndicator {
|
||||
super.backgroundColor,
|
||||
super.color,
|
||||
super.valueColor,
|
||||
this.strokeWidth = 4.0,
|
||||
this.strokeAlign = strokeAlignCenter,
|
||||
this.strokeWidth,
|
||||
this.strokeAlign,
|
||||
super.semanticsLabel,
|
||||
super.semanticsValue,
|
||||
this.strokeCap,
|
||||
this.constraints,
|
||||
this.trackGap,
|
||||
@Deprecated(
|
||||
'Use ProgressIndicatorTheme to customize the ProgressIndicator appearance. '
|
||||
'This feature was deprecated after v3.27.0-0.1.pre.'
|
||||
)
|
||||
this.year2023 = true,
|
||||
}) : _indicatorType = _ActivityIndicatorType.material;
|
||||
|
||||
/// Creates an adaptive progress indicator that is a
|
||||
/// [CupertinoActivityIndicator] in [TargetPlatform.iOS] & [TargetPlatform.macOS] and [CircularProgressIndicator] in
|
||||
/// material theme/non-Apple platforms.
|
||||
/// [CupertinoActivityIndicator] on [TargetPlatform.iOS] &
|
||||
/// [TargetPlatform.macOS] and a [CircularProgressIndicator] in material
|
||||
/// theme/non-Apple platforms.
|
||||
///
|
||||
/// The [value], [valueColor], [strokeWidth], [semanticsLabel], and
|
||||
/// [semanticsValue] will be ignored in iOS & macOS.
|
||||
/// The [valueColor], [strokeWidth], [strokeAlign], [strokeCap],
|
||||
/// [semanticsLabel], [semanticsValue], [trackGap], [year2023] will be
|
||||
/// ignored on iOS & macOS.
|
||||
///
|
||||
/// {@macro flutter.material.ProgressIndicator.ProgressIndicator}
|
||||
const CircularProgressIndicator.adaptive({
|
||||
@ -722,7 +766,14 @@ class CircularProgressIndicator extends ProgressIndicator {
|
||||
super.semanticsLabel,
|
||||
super.semanticsValue,
|
||||
this.strokeCap,
|
||||
this.strokeAlign = strokeAlignCenter,
|
||||
this.strokeAlign,
|
||||
this.constraints,
|
||||
this.trackGap,
|
||||
@Deprecated(
|
||||
'Use ProgressIndicatorTheme to customize the ProgressIndicator appearance. '
|
||||
'This feature was deprecated after v3.27.0-0.2.pre.'
|
||||
)
|
||||
this.year2023 = true,
|
||||
}) : _indicatorType = _ActivityIndicatorType.adaptive;
|
||||
|
||||
final _ActivityIndicatorType _indicatorType;
|
||||
@ -738,16 +789,19 @@ class CircularProgressIndicator extends ProgressIndicator {
|
||||
Color? get backgroundColor => super.backgroundColor;
|
||||
|
||||
/// The width of the line used to draw the circle.
|
||||
final double strokeWidth;
|
||||
final double? strokeWidth;
|
||||
|
||||
/// The relative position of the stroke on a [CircularProgressIndicator].
|
||||
///
|
||||
/// Values typically range from -1.0 ([strokeAlignInside], inside stroke)
|
||||
/// to 1.0 ([strokeAlignOutside], outside stroke),
|
||||
/// without any bound constraints (e.g., a value of -2.0 is not typical, but allowed).
|
||||
/// A value of 0 ([strokeAlignCenter], default) will center the border
|
||||
/// A value of 0 ([strokeAlignCenter]) will center the border
|
||||
/// on the edge of the widget.
|
||||
final double strokeAlign;
|
||||
///
|
||||
/// If [year2023] is true, then the default value is [strokeAlignCenter].
|
||||
/// Otherwise, the default value is [strokeAlignInside].
|
||||
final double? strokeAlign;
|
||||
|
||||
/// The progress indicator's line ending.
|
||||
///
|
||||
@ -770,6 +824,36 @@ class CircularProgressIndicator extends ProgressIndicator {
|
||||
/// degrees and end at 275 degrees.
|
||||
final StrokeCap? strokeCap;
|
||||
|
||||
/// Defines minimum and maximum sizes for a [CircularProgressIndicator].
|
||||
///
|
||||
/// If null, then the [ProgressIndicatorThemeData.constraints] will be used.
|
||||
/// Otherwise, defaults to a minimum width and height of 36 pixels.
|
||||
final BoxConstraints? constraints;
|
||||
|
||||
/// The gap between the active indicator and the background track.
|
||||
///
|
||||
/// If [year2023] is false or [ThemeData.useMaterial3] is false, then no track
|
||||
/// gap will be drawn.
|
||||
///
|
||||
/// Set [trackGap] to 0 to hide the track gap.
|
||||
///
|
||||
/// If null, then the [ProgressIndicatorThemeData.trackGap] will be used.
|
||||
/// If that is null, then defaults to 4.
|
||||
final double? trackGap;
|
||||
|
||||
/// When true, the [CircularProgressIndicator] will use the 2023 Material 3
|
||||
/// Design appearance.
|
||||
///
|
||||
/// Defaults to true. If false, the [CircularProgressIndicator] will use the
|
||||
/// latest Material 3 Design appearance, which was introduced in December 2023.
|
||||
///
|
||||
/// If [ThemeData.useMaterial3] is false, then this property is ignored.
|
||||
@Deprecated(
|
||||
'Use ProgressIndicatorTheme to customize the ProgressIndicator appearance. '
|
||||
'This feature was deprecated after v3.27.0-0.2.pre.'
|
||||
)
|
||||
final bool year2023;
|
||||
|
||||
/// The indicator stroke is drawn fully inside of the indicator path.
|
||||
///
|
||||
/// This is a constant for use with [strokeAlign].
|
||||
@ -857,30 +941,50 @@ class _CircularProgressIndicatorState extends State<CircularProgressIndicator> w
|
||||
}
|
||||
|
||||
Widget _buildMaterialIndicator(BuildContext context, double headValue, double tailValue, double offsetValue, double rotationValue) {
|
||||
final ProgressIndicatorThemeData defaults = Theme.of(context).useMaterial3
|
||||
? _CircularProgressIndicatorDefaultsM3(context)
|
||||
: _CircularProgressIndicatorDefaultsM2(context);
|
||||
final Color? trackColor = widget.backgroundColor ?? ProgressIndicatorTheme.of(context).circularTrackColor;
|
||||
|
||||
final ProgressIndicatorThemeData defaults = switch (Theme.of(context).useMaterial3) {
|
||||
true => widget.year2023
|
||||
? _CircularProgressIndicatorDefaultsM3Year2023(context, indeterminate: widget.value == null)
|
||||
: _CircularProgressIndicatorDefaultsM3(context, indeterminate: widget.value == null),
|
||||
false => _CircularProgressIndicatorDefaultsM2(context, indeterminate: widget.value == null),
|
||||
};
|
||||
final ProgressIndicatorThemeData indicatorTheme = ProgressIndicatorTheme.of(context);
|
||||
final Color? trackColor = widget.backgroundColor
|
||||
?? indicatorTheme.circularTrackColor
|
||||
?? defaults.circularTrackColor;
|
||||
final double strokeWidth = widget.strokeWidth
|
||||
?? indicatorTheme.strokeWidth
|
||||
?? defaults.strokeWidth!;
|
||||
final double strokeAlign = widget.strokeAlign
|
||||
?? indicatorTheme.strokeAlign
|
||||
?? defaults.strokeAlign!;
|
||||
final StrokeCap? strokeCap = widget.strokeCap
|
||||
?? indicatorTheme.strokeCap;
|
||||
final BoxConstraints constraints = widget.constraints
|
||||
?? indicatorTheme.constraints
|
||||
?? defaults.constraints!;
|
||||
final double? trackGap = widget.year2023
|
||||
? null
|
||||
: widget.trackGap ??
|
||||
indicatorTheme.trackGap ??
|
||||
defaults.trackGap;
|
||||
return widget._buildSemanticsWrapper(
|
||||
context: context,
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: _kMinCircularProgressIndicatorSize,
|
||||
minHeight: _kMinCircularProgressIndicatorSize,
|
||||
),
|
||||
constraints: constraints,
|
||||
child: CustomPaint(
|
||||
painter: _CircularProgressIndicatorPainter(
|
||||
backgroundColor: trackColor,
|
||||
trackColor: trackColor,
|
||||
valueColor: widget._getValueColor(context, defaultColor: defaults.color),
|
||||
value: widget.value, // may be null
|
||||
headValue: headValue, // remaining arguments are ignored if widget.value is not null
|
||||
tailValue: tailValue,
|
||||
offsetValue: offsetValue,
|
||||
rotationValue: rotationValue,
|
||||
strokeWidth: widget.strokeWidth,
|
||||
strokeAlign: widget.strokeAlign,
|
||||
strokeCap: widget.strokeCap,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeAlign: strokeAlign,
|
||||
strokeCap: strokeCap,
|
||||
trackGap: trackGap,
|
||||
year2023: widget.year2023,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1128,10 +1232,22 @@ class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState {
|
||||
final double opacity = valueColor.opacity;
|
||||
valueColor = valueColor.withOpacity(1.0);
|
||||
|
||||
final Color backgroundColor =
|
||||
widget.backgroundColor ??
|
||||
ProgressIndicatorTheme.of(context).refreshBackgroundColor ??
|
||||
Theme.of(context).canvasColor;
|
||||
final ProgressIndicatorThemeData defaults = switch (Theme.of(context).useMaterial3) {
|
||||
true => _CircularProgressIndicatorDefaultsM3Year2023(context, indeterminate: value == null),
|
||||
false => _CircularProgressIndicatorDefaultsM2(context, indeterminate: value == null),
|
||||
};
|
||||
final ProgressIndicatorThemeData indicatorTheme = ProgressIndicatorTheme.of(context);
|
||||
final Color backgroundColor = widget.backgroundColor
|
||||
?? indicatorTheme.refreshBackgroundColor
|
||||
?? Theme.of(context).canvasColor;
|
||||
final double strokeWidth = widget.strokeWidth
|
||||
?? indicatorTheme.strokeWidth
|
||||
?? defaults.strokeWidth!;
|
||||
final double strokeAlign = widget.strokeAlign
|
||||
?? indicatorTheme.strokeAlign
|
||||
?? defaults.strokeAlign!;
|
||||
final StrokeCap? strokeCap = widget.strokeCap
|
||||
?? indicatorTheme.strokeCap;
|
||||
|
||||
return widget._buildSemanticsWrapper(
|
||||
context: context,
|
||||
@ -1157,10 +1273,10 @@ class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState {
|
||||
tailValue: tailValue,
|
||||
offsetValue: offsetValue,
|
||||
rotationValue: rotationValue,
|
||||
strokeWidth: widget.strokeWidth,
|
||||
strokeAlign: widget.strokeAlign,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeAlign: strokeAlign,
|
||||
arrowheadScale: arrowheadScale,
|
||||
strokeCap: widget.strokeCap,
|
||||
strokeCap: strokeCap,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1175,13 +1291,26 @@ class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState {
|
||||
|
||||
// Hand coded defaults based on Material Design 2.
|
||||
class _CircularProgressIndicatorDefaultsM2 extends ProgressIndicatorThemeData {
|
||||
_CircularProgressIndicatorDefaultsM2(this.context);
|
||||
_CircularProgressIndicatorDefaultsM2(this.context, { required this.indeterminate });
|
||||
|
||||
final BuildContext context;
|
||||
late final ColorScheme _colors = Theme.of(context).colorScheme;
|
||||
final bool indeterminate;
|
||||
|
||||
@override
|
||||
Color get color => _colors.primary;
|
||||
|
||||
@override
|
||||
double? get strokeWidth => 4.0;
|
||||
|
||||
@override
|
||||
double? get strokeAlign => CircularProgressIndicator.strokeAlignCenter;
|
||||
|
||||
@override
|
||||
BoxConstraints get constraints => const BoxConstraints(
|
||||
minWidth: 36.0,
|
||||
minHeight: 36.0,
|
||||
);
|
||||
}
|
||||
|
||||
class _LinearProgressIndicatorDefaultsM2 extends ProgressIndicatorThemeData {
|
||||
@ -1200,6 +1329,29 @@ class _LinearProgressIndicatorDefaultsM2 extends ProgressIndicatorThemeData {
|
||||
double get linearMinHeight => 4.0;
|
||||
}
|
||||
|
||||
class _CircularProgressIndicatorDefaultsM3Year2023 extends ProgressIndicatorThemeData {
|
||||
_CircularProgressIndicatorDefaultsM3Year2023(this.context, { required this.indeterminate });
|
||||
|
||||
final BuildContext context;
|
||||
late final ColorScheme _colors = Theme.of(context).colorScheme;
|
||||
final bool indeterminate;
|
||||
|
||||
@override
|
||||
Color get color => _colors.primary;
|
||||
|
||||
@override
|
||||
double get strokeWidth => 4.0;
|
||||
|
||||
@override
|
||||
double? get strokeAlign => CircularProgressIndicator.strokeAlignCenter;
|
||||
|
||||
@override
|
||||
BoxConstraints get constraints => const BoxConstraints(
|
||||
minWidth: 36.0,
|
||||
minHeight: 36.0,
|
||||
);
|
||||
}
|
||||
|
||||
class _LinearProgressIndicatorDefaultsM3Year2023 extends ProgressIndicatorThemeData {
|
||||
_LinearProgressIndicatorDefaultsM3Year2023(this.context);
|
||||
|
||||
@ -1224,16 +1376,32 @@ class _LinearProgressIndicatorDefaultsM3Year2023 extends ProgressIndicatorThemeD
|
||||
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
||||
|
||||
class _CircularProgressIndicatorDefaultsM3 extends ProgressIndicatorThemeData {
|
||||
_CircularProgressIndicatorDefaultsM3(this.context);
|
||||
_CircularProgressIndicatorDefaultsM3(this.context, { required this.indeterminate });
|
||||
|
||||
final BuildContext context;
|
||||
late final ColorScheme _colors = Theme.of(context).colorScheme;
|
||||
final bool indeterminate;
|
||||
|
||||
@override
|
||||
Color get color => _colors.primary;
|
||||
|
||||
@override
|
||||
Color get circularTrackColor => _colors.secondaryContainer;
|
||||
Color? get circularTrackColor => indeterminate ? null : _colors.secondaryContainer;
|
||||
|
||||
@override
|
||||
double get strokeWidth => 4.0;
|
||||
|
||||
@override
|
||||
double? get strokeAlign => CircularProgressIndicator.strokeAlignInside;
|
||||
|
||||
@override
|
||||
BoxConstraints get constraints => const BoxConstraints(
|
||||
minWidth: 48.0,
|
||||
minHeight: 48.0,
|
||||
);
|
||||
|
||||
@override
|
||||
double? get trackGap => 4.0;
|
||||
}
|
||||
|
||||
class _LinearProgressIndicatorDefaultsM3 extends ProgressIndicatorThemeData {
|
||||
|
@ -42,6 +42,10 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
this.borderRadius,
|
||||
this.stopIndicatorColor,
|
||||
this.stopIndicatorRadius,
|
||||
this.strokeWidth,
|
||||
this.strokeAlign,
|
||||
this.strokeCap,
|
||||
this.constraints,
|
||||
this.trackGap,
|
||||
});
|
||||
|
||||
@ -85,7 +89,22 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
/// is false, then no stop indicator will be drawn.
|
||||
final double? stopIndicatorRadius;
|
||||
|
||||
/// Overrides the gap between the [LinearProgressIndicator].
|
||||
/// Overrides the stroke width of the [CircularProgressIndicator].
|
||||
final double? strokeWidth;
|
||||
|
||||
/// Overrides the stroke align of the [CircularProgressIndicator].
|
||||
final double? strokeAlign;
|
||||
|
||||
/// Overrides the stroke cap of the [CircularProgressIndicator].
|
||||
final StrokeCap? strokeCap;
|
||||
|
||||
/// Overrides the constraints of the [CircularProgressIndicator].
|
||||
final BoxConstraints? constraints;
|
||||
|
||||
/// Overrides the active indicator and the background track.
|
||||
///
|
||||
/// If [CircularProgressIndicator.year2023] is false or [ThemeData.useMaterial3]
|
||||
/// is false, then no track gap will be drawn.
|
||||
///
|
||||
/// If [LinearProgressIndicator.year2023] is false or [ThemeData.useMaterial3]
|
||||
/// is false, then no track gap will be drawn.
|
||||
@ -102,6 +121,10 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
BorderRadiusGeometry? borderRadius,
|
||||
Color? stopIndicatorColor,
|
||||
double? stopIndicatorRadius,
|
||||
double? strokeWidth,
|
||||
double? strokeAlign,
|
||||
StrokeCap? strokeCap,
|
||||
BoxConstraints? constraints,
|
||||
double? trackGap,
|
||||
}) {
|
||||
return ProgressIndicatorThemeData(
|
||||
@ -113,6 +136,10 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
borderRadius : borderRadius ?? this.borderRadius,
|
||||
stopIndicatorColor : stopIndicatorColor ?? this.stopIndicatorColor,
|
||||
stopIndicatorRadius : stopIndicatorRadius ?? this.stopIndicatorRadius,
|
||||
strokeWidth : strokeWidth ?? this.strokeWidth,
|
||||
strokeAlign : strokeAlign ?? this.strokeAlign,
|
||||
strokeCap : strokeCap ?? this.strokeCap,
|
||||
constraints: constraints ?? this.constraints,
|
||||
trackGap : trackGap ?? this.trackGap,
|
||||
);
|
||||
}
|
||||
@ -133,6 +160,10 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
borderRadius : BorderRadiusGeometry.lerp(a?.borderRadius, b?.borderRadius, t),
|
||||
stopIndicatorColor : Color.lerp(a?.stopIndicatorColor, b?.stopIndicatorColor, t),
|
||||
stopIndicatorRadius : lerpDouble(a?.stopIndicatorRadius, b?.stopIndicatorRadius, t),
|
||||
strokeWidth : lerpDouble(a?.strokeWidth, b?.strokeWidth, t),
|
||||
strokeAlign : lerpDouble(a?.strokeAlign, b?.strokeAlign, t),
|
||||
strokeCap : t < 0.5 ? a?.strokeCap : b?.strokeCap,
|
||||
constraints: BoxConstraints.lerp(a?.constraints, b?.constraints, t),
|
||||
trackGap : lerpDouble(a?.trackGap, b?.trackGap, t),
|
||||
);
|
||||
}
|
||||
@ -147,6 +178,10 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
borderRadius,
|
||||
stopIndicatorColor,
|
||||
stopIndicatorRadius,
|
||||
strokeAlign,
|
||||
strokeWidth,
|
||||
strokeCap,
|
||||
constraints,
|
||||
trackGap,
|
||||
);
|
||||
|
||||
@ -167,6 +202,10 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
&& other.borderRadius == borderRadius
|
||||
&& other.stopIndicatorColor == stopIndicatorColor
|
||||
&& other.stopIndicatorRadius == stopIndicatorRadius
|
||||
&& other.strokeAlign == strokeAlign
|
||||
&& other.strokeWidth == strokeWidth
|
||||
&& other.strokeCap == strokeCap
|
||||
&& other.constraints == constraints
|
||||
&& other.trackGap == trackGap;
|
||||
}
|
||||
|
||||
@ -181,6 +220,10 @@ class ProgressIndicatorThemeData with Diagnosticable {
|
||||
properties.add(DiagnosticsProperty<BorderRadiusGeometry>('borderRadius', borderRadius, defaultValue: null));
|
||||
properties.add(ColorProperty('stopIndicatorColor', stopIndicatorColor, defaultValue: null));
|
||||
properties.add(DoubleProperty('stopIndicatorRadius', stopIndicatorRadius, defaultValue: null));
|
||||
properties.add(DoubleProperty('strokeWidth', strokeWidth, defaultValue: null));
|
||||
properties.add(DoubleProperty('strokeAlign', strokeAlign, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<StrokeCap>('strokeCap', strokeCap, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
|
||||
properties.add(DoubleProperty('trackGap', trackGap, defaultValue: null));
|
||||
}
|
||||
}
|
||||
|
@ -1217,11 +1217,10 @@ void main() {
|
||||
expect((wrappedTheme as ProgressIndicatorTheme).data, themeData);
|
||||
});
|
||||
|
||||
testWidgets('default size of CircularProgressIndicator is 36x36 - M3', (WidgetTester tester) async {
|
||||
testWidgets('Material3 - Default size of CircularProgressIndicator', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme.copyWith(useMaterial3: true),
|
||||
home: const Scaffold(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Material(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
@ -1232,6 +1231,20 @@ void main() {
|
||||
expect(tester.getSize(find.byType(CircularProgressIndicator)), const Size(36, 36));
|
||||
});
|
||||
|
||||
testWidgets('Material3 - Default size of CircularProgressIndicator when year2023 is false', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Material(
|
||||
child: CircularProgressIndicator(year2023: false),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.getSize(find.byType(CircularProgressIndicator)), const Size(48, 48));
|
||||
});
|
||||
|
||||
testWidgets('RefreshProgressIndicator using fields correctly', (WidgetTester tester) async {
|
||||
Future<void> pumpIndicator(RefreshProgressIndicator indicator) {
|
||||
return tester.pumpWidget(Theme(data: theme, child: indicator));
|
||||
@ -1551,6 +1564,151 @@ void main() {
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Default determinate CircularProgressIndicator when year2023 is false', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: theme,
|
||||
home: const Center(
|
||||
child: CircularProgressIndicator(
|
||||
year2023: false,
|
||||
value: 0.5,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(tester.getSize(find.byType(CircularProgressIndicator)), equals(const Size(48, 48)));
|
||||
expect(
|
||||
find.byType(CircularProgressIndicator),
|
||||
paints
|
||||
// Track.
|
||||
..arc(
|
||||
rect: const Rect.fromLTRB(2.0, 2.0, 46.0, 46.0),
|
||||
color: theme.colorScheme.secondaryContainer,
|
||||
strokeWidth: 4.0,
|
||||
strokeCap: StrokeCap.round,
|
||||
style: PaintingStyle.stroke,
|
||||
)
|
||||
// Active indicator.
|
||||
..arc(
|
||||
rect: const Rect.fromLTRB(2.0, 2.0, 46.0, 46.0),
|
||||
color: theme.colorScheme.primary,
|
||||
strokeWidth: 4.0,
|
||||
strokeCap: StrokeCap.round,
|
||||
style: PaintingStyle.stroke,
|
||||
),
|
||||
);
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_determinate_year2023_false.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Default indeterminate CircularProgressIndicator when year2023 is false', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: theme,
|
||||
home: const Center(child: CircularProgressIndicator(year2023: false)),
|
||||
));
|
||||
|
||||
// Advance the animation.
|
||||
await tester.pump(const Duration(milliseconds: 200));
|
||||
|
||||
expect(tester.getSize(find.byType(CircularProgressIndicator)), equals(const Size(48, 48)));
|
||||
expect(
|
||||
find.byType(CircularProgressIndicator),
|
||||
paints
|
||||
// Active indicator.
|
||||
..arc(
|
||||
rect: const Rect.fromLTRB(2.0, 2.0, 46.0, 46.0),
|
||||
color: theme.colorScheme.primary,
|
||||
strokeWidth: 4.0,
|
||||
strokeCap: StrokeCap.round,
|
||||
style: PaintingStyle.stroke,
|
||||
),
|
||||
);
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_indeterminate_year2023_false.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('CircularProgressIndicator track gap can be adjusted when year2023 is false', (WidgetTester tester) async {
|
||||
Widget buildIndicator({ double? trackGap }) {
|
||||
return MaterialApp(
|
||||
home: Center(
|
||||
child: CircularProgressIndicator(
|
||||
year2023: false,
|
||||
trackGap: trackGap,
|
||||
value: 0.5,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildIndicator());
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_default_track_gap_year2023_false.png'),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(buildIndicator(trackGap: 12.0));
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_custom_track_gap_year2023_false.png'),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(buildIndicator(trackGap: 0.0));
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_no_track_gap_year2023_false.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Can override CircularProgressIndicator stroke cap when year2023 is false', (WidgetTester tester) async {
|
||||
const StrokeCap strokeCap = StrokeCap.square;
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Center(
|
||||
child: CircularProgressIndicator(
|
||||
year2023: false,
|
||||
strokeCap: strokeCap,
|
||||
value: 0.5,
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
expect(
|
||||
find.byType(CircularProgressIndicator),
|
||||
paints
|
||||
// Track.
|
||||
..arc(strokeCap: strokeCap)
|
||||
// Active indicator.
|
||||
..arc(strokeCap: strokeCap)
|
||||
);
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_custom_stroke_cap_year2023_false.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('CircularProgressIndicator.constraints can override default size', (WidgetTester tester) async {
|
||||
const Size size = Size(64, 64);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Center(
|
||||
child: CircularProgressIndicator(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: size.width,
|
||||
minHeight: size.height
|
||||
),
|
||||
value: 0.5,
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
expect(tester.getSize(find.byType(CircularProgressIndicator)), equals(size));
|
||||
});
|
||||
}
|
||||
|
||||
class _RefreshProgressIndicatorGolden extends StatefulWidget {
|
||||
|
@ -2,7 +2,14 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// reduced-test-set:
|
||||
// This file is run as part of a reduced test set in CI on Mac and Windows
|
||||
// machines.
|
||||
@Tags(<String>['reduced-test-set'])
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
@ -17,6 +24,46 @@ void main() {
|
||||
expect(identical(ProgressIndicatorThemeData.lerp(data, data, 0.5), data), true);
|
||||
});
|
||||
|
||||
testWidgets('ProgressIndicatorThemeData implements debugFillProperties', (WidgetTester tester) async {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
const ProgressIndicatorThemeData(
|
||||
color: Color(0XFF0000F1),
|
||||
linearTrackColor: Color(0XFF0000F2),
|
||||
linearMinHeight: 25.0,
|
||||
circularTrackColor: Color(0XFF0000F3),
|
||||
refreshBackgroundColor: Color(0XFF0000F4),
|
||||
borderRadius: BorderRadius.all(Radius.circular(8.0)),
|
||||
stopIndicatorColor: Color(0XFF0000F5),
|
||||
stopIndicatorRadius: 10.0,
|
||||
strokeWidth: 8.0,
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
strokeCap: StrokeCap.butt,
|
||||
constraints: BoxConstraints.tightFor(width: 80.0, height: 80.0),
|
||||
trackGap: 16.0,
|
||||
).debugFillProperties(builder);
|
||||
|
||||
final List<String> description = builder.properties
|
||||
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
||||
.map((DiagnosticsNode node) => node.toString())
|
||||
.toList();
|
||||
|
||||
expect(description, equalsIgnoringHashCodes(<String>[
|
||||
'color: Color(alpha: 1.0000, red: 0.0000, green: 0.0000, blue: 0.9451, colorSpace: ColorSpace.sRGB)',
|
||||
'linearTrackColor: Color(alpha: 1.0000, red: 0.0000, green: 0.0000, blue: 0.9490, colorSpace: ColorSpace.sRGB)',
|
||||
'linearMinHeight: 25.0',
|
||||
'circularTrackColor: Color(alpha: 1.0000, red: 0.0000, green: 0.0000, blue: 0.9529, colorSpace: ColorSpace.sRGB)',
|
||||
'refreshBackgroundColor: Color(alpha: 1.0000, red: 0.0000, green: 0.0000, blue: 0.9569, colorSpace: ColorSpace.sRGB)',
|
||||
'borderRadius: BorderRadius.circular(8.0)',
|
||||
'stopIndicatorColor: Color(alpha: 1.0000, red: 0.0000, green: 0.0000, blue: 0.9608, colorSpace: ColorSpace.sRGB)',
|
||||
'stopIndicatorRadius: 10.0',
|
||||
'strokeWidth: 8.0',
|
||||
'strokeAlign: 1.0',
|
||||
'strokeCap: StrokeCap.butt',
|
||||
'constraints: BoxConstraints(w=80.0, h=80.0)',
|
||||
'trackGap: 16.0'
|
||||
]));
|
||||
});
|
||||
|
||||
testWidgets('Can theme LinearProgressIndicator using ProgressIndicatorTheme', (WidgetTester tester) async {
|
||||
const Color color = Color(0XFF00FF00);
|
||||
const Color linearTrackColor = Color(0XFFFF0000);
|
||||
@ -62,7 +109,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Can theme LinearProgressIndicator with year2023 to false', (WidgetTester tester) async {
|
||||
testWidgets('Can theme LinearProgressIndicator when year2023 to false', (WidgetTester tester) async {
|
||||
const Color color = Color(0XFF00FF00);
|
||||
const Color linearTrackColor = Color(0XFFFF0000);
|
||||
const double linearMinHeight = 25.0;
|
||||
@ -182,4 +229,119 @@ void main() {
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Can theme CircularProgressIndicator using ProgressIndicatorTheme', (WidgetTester tester) async {
|
||||
const Color color = Color(0XFFFF0000);
|
||||
const Color circularTrackColor = Color(0XFF0000FF);
|
||||
const double strokeWidth = 8.0;
|
||||
const double strokeAlign = BorderSide.strokeAlignOutside;
|
||||
const StrokeCap strokeCap = StrokeCap.butt;
|
||||
const BoxConstraints constraints = BoxConstraints.tightFor(width: 80.0, height: 80.0);
|
||||
final ThemeData theme = ThemeData(
|
||||
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
||||
color: color,
|
||||
circularTrackColor: circularTrackColor,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeAlign: strokeAlign,
|
||||
strokeCap: strokeCap,
|
||||
constraints: constraints,
|
||||
),
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: const Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(
|
||||
value: 0.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
tester.getSize(find.byType(CircularProgressIndicator)),
|
||||
equals(Size(constraints.maxWidth, constraints.maxHeight)),
|
||||
);
|
||||
expect(
|
||||
find.byType(CircularProgressIndicator),
|
||||
paints
|
||||
// Track.
|
||||
..arc(
|
||||
color: circularTrackColor,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeCap: strokeCap,
|
||||
)
|
||||
// Active indicator.
|
||||
..arc(
|
||||
color: color,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeCap: strokeCap,
|
||||
),
|
||||
);
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_theme.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Can theme CircularProgressIndicator when year2023 to false', (WidgetTester tester) async {
|
||||
const Color color = Color(0XFFFF0000);
|
||||
const Color circularTrackColor = Color(0XFF0000FF);
|
||||
const double strokeWidth = 8.0;
|
||||
const double strokeAlign = BorderSide.strokeAlignOutside;
|
||||
const StrokeCap strokeCap = StrokeCap.butt;
|
||||
const BoxConstraints constraints = BoxConstraints.tightFor(width: 80.0, height: 80.0);
|
||||
const double trackGap = 12.0;
|
||||
final ThemeData theme = ThemeData(
|
||||
progressIndicatorTheme: const ProgressIndicatorThemeData(
|
||||
color: color,
|
||||
circularTrackColor: circularTrackColor,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeAlign: strokeAlign,
|
||||
strokeCap: strokeCap,
|
||||
constraints: constraints,
|
||||
trackGap: trackGap,
|
||||
),
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme,
|
||||
home: const Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(
|
||||
year2023: false,
|
||||
value: 0.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
tester.getSize(find.byType(CircularProgressIndicator)),
|
||||
equals(Size(constraints.maxWidth, constraints.maxHeight)),
|
||||
);
|
||||
expect(
|
||||
find.byType(CircularProgressIndicator),
|
||||
paints
|
||||
// Track.
|
||||
..arc(
|
||||
color: circularTrackColor,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeCap: strokeCap,
|
||||
)
|
||||
// Active indicator.
|
||||
..arc(
|
||||
color: color,
|
||||
strokeWidth: strokeWidth,
|
||||
strokeCap: strokeCap,
|
||||
),
|
||||
);
|
||||
await expectLater(
|
||||
find.byType(CircularProgressIndicator),
|
||||
matchesGoldenFile('circular_progress_indicator_theme_year2023_false.png'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user