diff --git a/dev/tools/gen_defaults/bin/gen_defaults.dart b/dev/tools/gen_defaults/bin/gen_defaults.dart index 21157d72cb5..ef1f32af647 100644 --- a/dev/tools/gen_defaults/bin/gen_defaults.dart +++ b/dev/tools/gen_defaults/bin/gen_defaults.dart @@ -31,6 +31,7 @@ import 'package:gen_defaults/input_chip_template.dart'; import 'package:gen_defaults/input_decorator_template.dart'; import 'package:gen_defaults/navigation_bar_template.dart'; import 'package:gen_defaults/navigation_rail_template.dart'; +import 'package:gen_defaults/progress_indicator_template.dart'; import 'package:gen_defaults/radio_template.dart'; import 'package:gen_defaults/surface_tint.dart'; import 'package:gen_defaults/switch_template.dart'; @@ -80,6 +81,8 @@ Future main(List args) async { 'navigation_drawer.json', 'navigation_rail.json', 'palette.json', + 'progress_indicator_circular.json', + 'progress_indicator_linear.json', 'radio_button.json', 'segmented_button_outlined.json', 'shape.json', @@ -126,6 +129,7 @@ Future main(List args) async { InputDecoratorTemplate('InputDecorator', '$materialLib/input_decorator.dart', tokens).updateFile(); NavigationBarTemplate('NavigationBar', '$materialLib/navigation_bar.dart', tokens).updateFile(); NavigationRailTemplate('NavigationRail', '$materialLib/navigation_rail.dart', tokens).updateFile(); + ProgressIndicatorTemplate('ProgressIndicator', '$materialLib/progress_indicator.dart', tokens).updateFile(); RadioTemplate('Radio', '$materialLib/radio.dart', tokens).updateFile(); SurfaceTintTemplate('SurfaceTint', '$materialLib/elevation_overlay.dart', tokens).updateFile(); SwitchTemplate('Switch', '$materialLib/switch.dart', tokens).updateFile(); diff --git a/dev/tools/gen_defaults/lib/progress_indicator_template.dart b/dev/tools/gen_defaults/lib/progress_indicator_template.dart new file mode 100644 index 00000000000..896be2e8d89 --- /dev/null +++ b/dev/tools/gen_defaults/lib/progress_indicator_template.dart @@ -0,0 +1,42 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'template.dart'; + +class ProgressIndicatorTemplate extends TokenTemplate { + const ProgressIndicatorTemplate(super.blockName, super.fileName, super.tokens, { + super.colorSchemePrefix = '_colors.', + }); + + @override + String generate() => ''' +class _Circular${blockName}DefaultsM3 extends ProgressIndicatorThemeData { + _Circular${blockName}DefaultsM3(this.context); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + + static const double circularProgressIndicatorSize = ${tokens['md.comp.circular-progress-indicator.size']}; + + @override + Color get color => ${componentColor('md.comp.circular-progress-indicator.active-indicator')}; +} + +class _Linear${blockName}DefaultsM3 extends ProgressIndicatorThemeData { + _Linear${blockName}DefaultsM3(this.context); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + + @override + Color get color => ${componentColor('md.comp.linear-progress-indicator.active-indicator')}; + + @override + Color get linearTrackColor => ${componentColor('md.comp.linear-progress-indicator.track')}; + + @override + double get linearMinHeight => ${tokens['md.comp.linear-progress-indicator.track.height']}; +} +'''; +} diff --git a/packages/flutter/lib/src/material/progress_indicator.dart b/packages/flutter/lib/src/material/progress_indicator.dart index b533186399f..9673a09a97d 100644 --- a/packages/flutter/lib/src/material/progress_indicator.dart +++ b/packages/flutter/lib/src/material/progress_indicator.dart @@ -108,11 +108,11 @@ abstract class ProgressIndicator extends StatefulWidget { /// {@endtemplate} final String? semanticsValue; - Color _getValueColor(BuildContext context) { - return - valueColor?.value ?? + Color _getValueColor(BuildContext context, {Color? defaultColor}) { + return valueColor?.value ?? color ?? ProgressIndicatorTheme.of(context).color ?? + defaultColor ?? Theme.of(context).colorScheme.primary; } @@ -331,12 +331,17 @@ class _LinearProgressIndicatorState extends State with } Widget _buildIndicator(BuildContext context, double animationValue, TextDirection textDirection) { + final ProgressIndicatorThemeData defaults = Theme.of(context).useMaterial3 + ? _LinearProgressIndicatorDefaultsM3(context) + : _LinearProgressIndicatorDefaultsM2(context); + final ProgressIndicatorThemeData indicatorTheme = ProgressIndicatorTheme.of(context); - final Color trackColor = - widget.backgroundColor ?? + final Color trackColor = widget.backgroundColor ?? indicatorTheme.linearTrackColor ?? - Theme.of(context).colorScheme.background; - final double minHeight = widget.minHeight ?? indicatorTheme.linearMinHeight ?? 4.0; + defaults.linearTrackColor!; + final double minHeight = widget.minHeight ?? + indicatorTheme.linearMinHeight ?? + defaults.linearMinHeight!; return widget._buildSemanticsWrapper( context: context, @@ -348,7 +353,7 @@ class _LinearProgressIndicatorState extends State with child: CustomPaint( painter: _LinearProgressIndicatorPainter( backgroundColor: trackColor, - valueColor: widget._getValueColor(context), + valueColor: widget._getValueColor(context, defaultColor: defaults.color), value: widget.value, // may be null animationValue: animationValue, // ignored if widget.value is not null textDirection: textDirection, @@ -580,28 +585,43 @@ class _CircularProgressIndicatorState extends State 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; + Widget progressIndicator = Container( + constraints: const BoxConstraints( + minWidth: _kMinCircularProgressIndicatorSize, + minHeight: _kMinCircularProgressIndicatorSize, + ), + child: CustomPaint( + painter: _CircularProgressIndicatorPainter( + backgroundColor: 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, + ), + ), + ); + + if (Theme.of(context).useMaterial3) { + progressIndicator = SizedBox( + height: _CircularProgressIndicatorDefaultsM3.circularProgressIndicatorSize, + width: _CircularProgressIndicatorDefaultsM3.circularProgressIndicatorSize, + child: Center( + child: progressIndicator + ), + ); + } + return widget._buildSemanticsWrapper( context: context, - child: Container( - constraints: const BoxConstraints( - minWidth: _kMinCircularProgressIndicatorSize, - minHeight: _kMinCircularProgressIndicatorSize, - ), - child: CustomPaint( - painter: _CircularProgressIndicatorPainter( - backgroundColor: trackColor, - valueColor: widget._getValueColor(context), - 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, - ), - ), - ), + child: progressIndicator, ); } @@ -866,3 +886,69 @@ class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState { ); } } + +// Hand coded defaults based on Material Design 2. +class _CircularProgressIndicatorDefaultsM2 extends ProgressIndicatorThemeData { + _CircularProgressIndicatorDefaultsM2(this.context); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + + @override + Color get color => _colors.primary; +} + +class _LinearProgressIndicatorDefaultsM2 extends ProgressIndicatorThemeData { + _LinearProgressIndicatorDefaultsM2(this.context); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + + @override + Color get color => _colors.primary; + + @override + Color get linearTrackColor => _colors.background; + + @override + double get linearMinHeight => 4.0; +} + +// BEGIN GENERATED TOKEN PROPERTIES - ProgressIndicator + +// Do not edit by hand. The code between the "BEGIN GENERATED" and +// "END GENERATED" comments are generated from data in the Material +// Design token database by the script: +// dev/tools/gen_defaults/bin/gen_defaults.dart. + +// Token database version: v0_132 + +class _CircularProgressIndicatorDefaultsM3 extends ProgressIndicatorThemeData { + _CircularProgressIndicatorDefaultsM3(this.context); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + + static const double circularProgressIndicatorSize = 48.0; + + @override + Color get color => _colors.primary; +} + +class _LinearProgressIndicatorDefaultsM3 extends ProgressIndicatorThemeData { + _LinearProgressIndicatorDefaultsM3(this.context); + + final BuildContext context; + late final ColorScheme _colors = Theme.of(context).colorScheme; + + @override + Color get color => _colors.primary; + + @override + Color get linearTrackColor => _colors.surfaceVariant; + + @override + double get linearMinHeight => 4.0; +} + +// END GENERATED TOKEN PROPERTIES - ProgressIndicator diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart index 38f38c89b2a..30cd86748e8 100644 --- a/packages/flutter/lib/src/material/theme_data.dart +++ b/packages/flutter/lib/src/material/theme_data.dart @@ -1266,6 +1266,7 @@ class ThemeData with Diagnosticable { /// * Lists: [ListTile] /// * Navigation bar: [NavigationBar] (new, replacing [BottomNavigationBar]) /// * [Navigation rail](https://m3.material.io/components/navigation-rail): [NavigationRail] + /// * Progress indicators: [CircularProgressIndicator], [LinearProgressIndicator] /// * Radio button: [Radio] /// * Switch: [Switch] /// * Top app bar: [AppBar] diff --git a/packages/flutter/test/material/progress_indicator_test.dart b/packages/flutter/test/material/progress_indicator_test.dart index 6199de2761c..96bc89d3f1b 100644 --- a/packages/flutter/test/material/progress_indicator_test.dart +++ b/packages/flutter/test/material/progress_indicator_test.dart @@ -20,6 +20,7 @@ import 'package:flutter_test/flutter_test.dart'; import '../rendering/mock_canvas.dart'; void main() { + final ThemeData theme = ThemeData(); // The "can be constructed" tests that follow are primarily to ensure that any // animations started by the progress indicators are stopped at dispose() time. @@ -27,12 +28,15 @@ void main() { testWidgets('LinearProgressIndicator(value: 0.0) can be constructed and has empty semantics by default', (WidgetTester tester) async { final SemanticsHandle handle = tester.ensureSemantics(); await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator(value: 0.0), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator(value: 0.0), + ), ), ), ), @@ -45,12 +49,15 @@ void main() { testWidgets('LinearProgressIndicator(value: null) can be constructed and has empty semantics by default', (WidgetTester tester) async { final SemanticsHandle handle = tester.ensureSemantics(); await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.rtl, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator(), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.rtl, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator(), + ), ), ), ), @@ -62,12 +69,15 @@ void main() { testWidgets('LinearProgressIndicator custom minHeight', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator(value: 0.25, minHeight: 2.0), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator(value: 0.25, minHeight: 2.0), + ), ), ), ), @@ -82,7 +92,7 @@ void main() { // Same test, but using the theme await tester.pumpWidget( Theme( - data: ThemeData( + data: theme.copyWith( progressIndicatorTheme: const ProgressIndicatorThemeData( linearMinHeight: 2.0, ), @@ -108,12 +118,15 @@ void main() { testWidgets('LinearProgressIndicator paint (LTR)', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator(value: 0.25), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator(value: 0.25), + ), ), ), ), @@ -131,12 +144,15 @@ void main() { testWidgets('LinearProgressIndicator paint (RTL)', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.rtl, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator(value: 0.25), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.rtl, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator(value: 0.25), + ), ), ), ), @@ -154,12 +170,15 @@ void main() { testWidgets('LinearProgressIndicator indeterminate (LTR)', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator(), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator(), + ), ), ), ), @@ -181,12 +200,15 @@ void main() { testWidgets('LinearProgressIndicator paint (RTL)', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.rtl, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator(), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.rtl, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator(), + ), ), ), ), @@ -209,16 +231,19 @@ void main() { testWidgets('LinearProgressIndicator with colors', (WidgetTester tester) async { // With valueColor & color provided await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator( - value: 0.25, - backgroundColor: Colors.black, - color: Colors.blue, - valueColor: AlwaysStoppedAnimation(Colors.white), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator( + value: 0.25, + backgroundColor: Colors.black, + color: Colors.blue, + valueColor: AlwaysStoppedAnimation(Colors.white), + ), ), ), ), @@ -235,15 +260,18 @@ void main() { // With just color provided await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator( - value: 0.25, - backgroundColor: Colors.black, - color: Colors.white12, + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator( + value: 0.25, + backgroundColor: Colors.black, + color: Colors.white12, + ), ), ), ), @@ -260,10 +288,9 @@ void main() { // With no color provided const Color primaryColor = Color(0xff008800); - final ThemeData theme = ThemeData(colorScheme: ColorScheme.fromSwatch().copyWith(primary: primaryColor)); await tester.pumpWidget( Theme( - data: theme, + data: theme.copyWith(colorScheme: ColorScheme.fromSwatch().copyWith(primary: primaryColor)), child: const Directionality( textDirection: TextDirection.ltr, child: Center( @@ -291,7 +318,7 @@ void main() { const Color indicatorColor = Color(0xff0000ff); await tester.pumpWidget( Theme( - data: ThemeData( + data: theme.copyWith( progressIndicatorTheme: const ProgressIndicatorThemeData( color: indicatorColor, linearTrackColor: Colors.black, @@ -323,15 +350,18 @@ void main() { testWidgets('LinearProgressIndicator with animation with null colors', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: LinearProgressIndicator( - value: 0.25, - valueColor: AlwaysStoppedAnimation(null), - backgroundColor: Colors.black, + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: LinearProgressIndicator( + value: 0.25, + valueColor: AlwaysStoppedAnimation(null), + backgroundColor: Colors.black, + ), ), ), ), @@ -349,10 +379,13 @@ void main() { testWidgets('CircularProgressIndicator(value: 0.0) can be constructed and has value semantics by default', (WidgetTester tester) async { final SemanticsHandle handle = tester.ensureSemantics(); await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: CircularProgressIndicator(value: 0.0), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: CircularProgressIndicator(value: 0.0), + ), ), ), ); @@ -367,8 +400,11 @@ void main() { testWidgets('CircularProgressIndicator(value: null) can be constructed and has empty semantics by default', (WidgetTester tester) async { final SemanticsHandle handle = tester.ensureSemantics(); await tester.pumpWidget( - const Center( - child: CircularProgressIndicator(), + Theme( + data: theme, + child: const Center( + child: CircularProgressIndicator(), + ), ), ); @@ -377,25 +413,31 @@ void main() { }); testWidgets('LinearProgressIndicator causes a repaint when it changes', (WidgetTester tester) async { - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: ListView(children: const [LinearProgressIndicator(value: 0.0)]), + await tester.pumpWidget(Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: ListView(children: const [LinearProgressIndicator(value: 0.0)]), + ), )); final List layers1 = tester.layers; - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: ListView(children: const [LinearProgressIndicator(value: 0.5)]), + await tester.pumpWidget(Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: ListView(children: const [LinearProgressIndicator(value: 0.5)]), + ), )); final List layers2 = tester.layers; expect(layers1, isNot(equals(layers2))); }); testWidgets('CircularProgressIndicator stoke width', (WidgetTester tester) async { - await tester.pumpWidget(const CircularProgressIndicator()); + await tester.pumpWidget(Theme(data: theme, child: const CircularProgressIndicator())); expect(find.byType(CircularProgressIndicator), paints..arc(strokeWidth: 4.0)); - await tester.pumpWidget(const CircularProgressIndicator(strokeWidth: 16.0)); + await tester.pumpWidget(Theme(data: theme, child: const CircularProgressIndicator(strokeWidth: 16.0))); expect(find.byType(CircularProgressIndicator), paints..arc(strokeWidth: 16.0)); }); @@ -406,39 +448,48 @@ void main() { const Color red = Color(0xFFFF0000); // With valueColor & color provided - await tester.pumpWidget(const CircularProgressIndicator( - color: red, - valueColor: AlwaysStoppedAnimation(blue), + await tester.pumpWidget(Theme( + data: theme, + child: const CircularProgressIndicator( + color: red, + valueColor: AlwaysStoppedAnimation(blue), + ), )); expect(find.byType(CircularProgressIndicator), paintsExactlyCountTimes(#drawArc, 1)); expect(find.byType(CircularProgressIndicator), paints..arc(color: blue)); // With just color provided - await tester.pumpWidget(const CircularProgressIndicator( - color: red, + await tester.pumpWidget(Theme( + data: theme, + child: const CircularProgressIndicator( + color: red, + ), )); expect(find.byType(CircularProgressIndicator), paintsExactlyCountTimes(#drawArc, 1)); expect(find.byType(CircularProgressIndicator), paints..arc(color: red)); // With no color provided await tester.pumpWidget(Theme( - data: ThemeData(colorScheme: ColorScheme.fromSwatch().copyWith(primary: green)), + data: theme.copyWith(colorScheme: ColorScheme.fromSwatch().copyWith(primary: green)), child: const CircularProgressIndicator(), )); expect(find.byType(CircularProgressIndicator), paintsExactlyCountTimes(#drawArc, 1)); expect(find.byType(CircularProgressIndicator), paints..arc(color: green)); // With background - await tester.pumpWidget(const CircularProgressIndicator( - backgroundColor: green, - color: blue, + await tester.pumpWidget(Theme( + data: theme, + child: const CircularProgressIndicator( + backgroundColor: green, + color: blue, + ), )); expect(find.byType(CircularProgressIndicator), paintsExactlyCountTimes(#drawArc, 2)); expect(find.byType(CircularProgressIndicator), paints..arc(color: green)..arc(color: blue)); // With ProgressIndicatorTheme await tester.pumpWidget(Theme( - data: ThemeData(progressIndicatorTheme: const ProgressIndicatorThemeData( + data: theme.copyWith(progressIndicatorTheme: const ProgressIndicatorThemeData( color: green, circularTrackColor: blue, )), @@ -454,32 +505,41 @@ void main() { const Color red = Color(0xFFFF0000); // With valueColor & color provided - await tester.pumpWidget(const RefreshProgressIndicator( - color: red, - valueColor: AlwaysStoppedAnimation(blue), + await tester.pumpWidget(Theme( + data: theme, + child: const RefreshProgressIndicator( + color: red, + valueColor: AlwaysStoppedAnimation(blue), + ), )); expect(find.byType(RefreshProgressIndicator), paintsExactlyCountTimes(#drawArc, 1)); expect(find.byType(RefreshProgressIndicator), paints..arc(color: blue)); // With just color provided - await tester.pumpWidget(const RefreshProgressIndicator( - color: red, + await tester.pumpWidget(Theme( + data: theme, + child: const RefreshProgressIndicator( + color: red, + ), )); expect(find.byType(RefreshProgressIndicator), paintsExactlyCountTimes(#drawArc, 1)); expect(find.byType(RefreshProgressIndicator), paints..arc(color: red)); // With no color provided await tester.pumpWidget(Theme( - data: ThemeData(colorScheme: ColorScheme.fromSwatch().copyWith(primary: green)), + data: theme.copyWith(colorScheme: ColorScheme.fromSwatch().copyWith(primary: green)), child: const RefreshProgressIndicator(), )); expect(find.byType(RefreshProgressIndicator), paintsExactlyCountTimes(#drawArc, 1)); expect(find.byType(RefreshProgressIndicator), paints..arc(color: green)); // With background - await tester.pumpWidget(const RefreshProgressIndicator( - color: blue, - backgroundColor: green, + await tester.pumpWidget(Theme( + data: theme, + child: const RefreshProgressIndicator( + color: blue, + backgroundColor: green, + ), )); expect(find.byType(RefreshProgressIndicator), paintsExactlyCountTimes(#drawArc, 1)); expect(find.byType(RefreshProgressIndicator), paints..arc(color: blue)); @@ -492,7 +552,7 @@ void main() { // With ProgressIndicatorTheme await tester.pumpWidget(Theme( - data: ThemeData(progressIndicatorTheme: const ProgressIndicatorThemeData( + data: theme.copyWith(progressIndicatorTheme: const ProgressIndicatorThemeData( color: green, refreshBackgroundColor: blue, )), @@ -512,12 +572,15 @@ void main() { // Regression test for https://github.com/flutter/flutter/issues/13782 await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 200.0, - child: RefreshProgressIndicator(), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 200.0, + child: RefreshProgressIndicator(), + ), ), ), ), @@ -551,14 +614,17 @@ void main() { double? progressValue; late StateSetter setState; await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: StatefulBuilder( - builder: (BuildContext context, StateSetter setter) { - setState = setter; - return CircularProgressIndicator(value: progressValue); - }, + Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: StatefulBuilder( + builder: (BuildContext context, StateSetter setter) { + setState = setter; + return CircularProgressIndicator(value: progressValue); + }, + ), ), ), ), @@ -576,13 +642,16 @@ void main() { testWidgets('LinearProgressIndicator with height 12.0', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 100.0, - height: 12.0, - child: LinearProgressIndicator(value: 0.25), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 100.0, + height: 12.0, + child: LinearProgressIndicator(value: 0.25), + ), ), ), ), @@ -598,13 +667,16 @@ void main() { testWidgets('LinearProgressIndicator with a height less than the minimum', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 100.0, - height: 3.0, - child: LinearProgressIndicator(value: 0.25), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 100.0, + height: 3.0, + child: LinearProgressIndicator(value: 0.25), + ), ), ), ), @@ -620,13 +692,16 @@ void main() { testWidgets('LinearProgressIndicator with default height', (WidgetTester tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Center( - child: SizedBox( - width: 100.0, - height: 4.0, - child: LinearProgressIndicator(value: 0.25), + Theme( + data: theme, + child: const Directionality( + textDirection: TextDirection.ltr, + child: Center( + child: SizedBox( + width: 100.0, + height: 4.0, + child: LinearProgressIndicator(value: 0.25), + ), ), ), ), @@ -646,13 +721,16 @@ void main() { const String label = 'Label'; const String value = '25%'; await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: LinearProgressIndicator( - key: key, - value: 0.25, - semanticsLabel: label, - semanticsValue: value, + Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: LinearProgressIndicator( + key: key, + value: 0.25, + semanticsLabel: label, + semanticsValue: value, + ), ), ), ); @@ -671,12 +749,15 @@ void main() { final GlobalKey key = GlobalKey(); const String label = 'Label'; await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: LinearProgressIndicator( - key: key, - value: 0.25, - semanticsLabel: label, + Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: LinearProgressIndicator( + key: key, + value: 0.25, + semanticsLabel: label, + ), ), ), ); @@ -694,11 +775,14 @@ void main() { final SemanticsHandle handle = tester.ensureSemantics(); final GlobalKey key = GlobalKey(); await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: LinearProgressIndicator( - key: key, - value: 0.25, + Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: LinearProgressIndicator( + key: key, + value: 0.25, + ), ), ), ); @@ -713,12 +797,15 @@ void main() { final GlobalKey key = GlobalKey(); const String label = 'Progress'; await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: LinearProgressIndicator( - key: key, - value: 0.25, - semanticsLabel: label, + Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: LinearProgressIndicator( + key: key, + value: 0.25, + semanticsLabel: label, + ), ), ), ); @@ -737,13 +824,16 @@ void main() { const String label = 'Label'; const String value = '25%'; await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: CircularProgressIndicator( - key: key, - value: 0.25, - semanticsLabel: label, - semanticsValue: value, + Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: CircularProgressIndicator( + key: key, + value: 0.25, + semanticsLabel: label, + semanticsValue: value, + ), ), ), ); @@ -763,12 +853,15 @@ void main() { const String label = 'Label'; const String value = '25%'; await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: RefreshProgressIndicator( - key: key, - semanticsLabel: label, - semanticsValue: value, + Theme( + data: theme, + child: Directionality( + textDirection: TextDirection.ltr, + child: RefreshProgressIndicator( + key: key, + semanticsLabel: label, + semanticsValue: value, + ), ), ), ); @@ -805,8 +898,9 @@ void main() { 'Adaptive CircularProgressIndicator displays CupertinoActivityIndicator in iOS', (WidgetTester tester) async { await tester.pumpWidget( - const MaterialApp( - home: Scaffold( + MaterialApp( + theme: ThemeData(), + home: const Scaffold( body: Material( child: CircularProgressIndicator.adaptive(), ), @@ -826,8 +920,9 @@ void main() { 'Adaptive CircularProgressIndicator can use backgroundColor to change tick color for iOS', (WidgetTester tester) async { await tester.pumpWidget( - const MaterialApp( - home: Scaffold( + MaterialApp( + theme: ThemeData(), + home: const Scaffold( body: Material( child: CircularProgressIndicator.adaptive( backgroundColor: Color(0xFF5D3FD3), @@ -854,8 +949,9 @@ void main() { 'Adaptive CircularProgressIndicator does not display CupertinoActivityIndicator in non-iOS', (WidgetTester tester) async { await tester.pumpWidget( - const MaterialApp( - home: Scaffold( + MaterialApp( + theme: theme, + home: const Scaffold( body: Material( child: CircularProgressIndicator.adaptive(), ), @@ -893,7 +989,7 @@ void main() { ); await tester.pumpWidget(MaterialApp( - home: progressTheme, + home: Theme(data: theme, child: progressTheme), )); final Widget wrappedTheme = progressTheme.wrap(builderContext, Container()); @@ -903,6 +999,21 @@ void main() { expect(wrappedTheme, isInstanceOf()); expect((wrappedTheme as ProgressIndicatorTheme).data, themeData); }); + + testWidgets('default size of CircularProgressIndicator is 48x48 - M3', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + theme: theme.copyWith(useMaterial3: true), + home: const Scaffold( + body: Material( + child: CircularProgressIndicator(), + ), + ), + ), + ); + + expect(tester.getSize(find.byType(CircularProgressIndicator)), const Size(48, 48)); + }); } class _RefreshProgressIndicatorGolden extends StatefulWidget {