Skip to content

Commit 7f75d24

Browse files
authored
Add Material 3 ProgressIndicator examples (#113950)
1 parent b0e7c9c commit 7f75d24

9 files changed

+340
-27
lines changed

examples/api/lib/material/progress_indicator/circular_progress_indicator.0.dart

+10-13
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,35 @@
66
77
import 'package:flutter/material.dart';
88

9-
void main() => runApp(const MyApp());
9+
void main() => runApp(const ProgressIndicatorApp());
1010

11-
class MyApp extends StatelessWidget {
12-
const MyApp({super.key});
13-
14-
static const String _title = 'Flutter Code Sample';
11+
class ProgressIndicatorApp extends StatelessWidget {
12+
const ProgressIndicatorApp({super.key});
1513

1614
@override
1715
Widget build(BuildContext context) {
1816
return const MaterialApp(
19-
title: _title,
20-
home: MyStatefulWidget(),
17+
home: ProgressIndicatorExample(),
2118
);
2219
}
2320
}
2421

25-
class MyStatefulWidget extends StatefulWidget {
26-
const MyStatefulWidget({super.key});
22+
class ProgressIndicatorExample extends StatefulWidget {
23+
const ProgressIndicatorExample({super.key});
2724

2825
@override
29-
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
26+
State<ProgressIndicatorExample> createState() => _ProgressIndicatorExampleState();
3027
}
3128

32-
/// [AnimationController]s can be created with `vsync: this` because of
33-
/// [TickerProviderStateMixin].
34-
class _MyStatefulWidgetState extends State<MyStatefulWidget>
29+
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
3530
with TickerProviderStateMixin {
3631
late AnimationController controller;
3732

3833
@override
3934
void initState() {
4035
controller = AnimationController(
36+
/// [AnimationController]s can be created with `vsync: this` because of
37+
/// [TickerProviderStateMixin].
4138
vsync: this,
4239
duration: const Duration(seconds: 5),
4340
)..addListener(() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
/// Flutter code sample for [CircularProgressIndicator].
6+
7+
import 'package:flutter/material.dart';
8+
9+
void main() => runApp(const ProgressIndicatorApp());
10+
11+
class ProgressIndicatorApp extends StatelessWidget {
12+
const ProgressIndicatorApp({super.key});
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return MaterialApp(
17+
theme: ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4)),
18+
home: const ProgressIndicatorExample(),
19+
);
20+
}
21+
}
22+
23+
class ProgressIndicatorExample extends StatefulWidget {
24+
const ProgressIndicatorExample({super.key});
25+
26+
@override
27+
State<ProgressIndicatorExample> createState() => _ProgressIndicatorExampleState();
28+
}
29+
30+
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
31+
with TickerProviderStateMixin {
32+
late AnimationController controller;
33+
bool determinate = false;
34+
35+
@override
36+
void initState() {
37+
controller = AnimationController(
38+
/// [AnimationController]s can be created with `vsync: this` because of
39+
/// [TickerProviderStateMixin].
40+
vsync: this,
41+
duration: const Duration(seconds: 2),
42+
)..addListener(() {
43+
setState(() {});
44+
});
45+
controller.repeat(reverse: true);
46+
super.initState();
47+
}
48+
49+
@override
50+
void dispose() {
51+
controller.dispose();
52+
super.dispose();
53+
}
54+
55+
@override
56+
Widget build(BuildContext context) {
57+
return Scaffold(
58+
body: Padding(
59+
padding: const EdgeInsets.all(20.0),
60+
child: Column(
61+
mainAxisAlignment: MainAxisAlignment.center,
62+
children: <Widget>[
63+
Text(
64+
'Circular progress indicator',
65+
style: Theme.of(context).textTheme.titleLarge,
66+
),
67+
const SizedBox(height: 30),
68+
CircularProgressIndicator(
69+
value: controller.value,
70+
semanticsLabel: 'Circular progress indicator',
71+
),
72+
const SizedBox(height: 10),
73+
Row(
74+
children: <Widget>[
75+
Expanded(
76+
child: Text(
77+
'determinate Mode',
78+
style: Theme.of(context).textTheme.titleSmall,
79+
),
80+
),
81+
Switch(
82+
value: determinate,
83+
onChanged: (bool value) {
84+
setState(() {
85+
determinate = value;
86+
if (determinate) {
87+
controller.stop();
88+
} else {
89+
controller..forward(from: controller.value)..repeat();
90+
}
91+
});
92+
},
93+
),
94+
],
95+
),
96+
],
97+
),
98+
),
99+
);
100+
}
101+
}

examples/api/lib/material/progress_indicator/linear_progress_indicator.0.dart

+10-13
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,35 @@
66
77
import 'package:flutter/material.dart';
88

9-
void main() => runApp(const MyApp());
9+
void main() => runApp(const ProgressIndicatorApp());
1010

11-
class MyApp extends StatelessWidget {
12-
const MyApp({super.key});
13-
14-
static const String _title = 'Flutter Code Sample';
11+
class ProgressIndicatorApp extends StatelessWidget {
12+
const ProgressIndicatorApp({super.key});
1513

1614
@override
1715
Widget build(BuildContext context) {
1816
return const MaterialApp(
19-
title: _title,
20-
home: MyStatefulWidget(),
17+
home: ProgressIndicatorExample(),
2118
);
2219
}
2320
}
2421

25-
class MyStatefulWidget extends StatefulWidget {
26-
const MyStatefulWidget({super.key});
22+
class ProgressIndicatorExample extends StatefulWidget {
23+
const ProgressIndicatorExample({super.key});
2724

2825
@override
29-
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
26+
State<ProgressIndicatorExample> createState() => _ProgressIndicatorExampleState();
3027
}
3128

32-
/// [AnimationController]s can be created with `vsync: this` because of
33-
/// [TickerProviderStateMixin].
34-
class _MyStatefulWidgetState extends State<MyStatefulWidget>
29+
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
3530
with TickerProviderStateMixin {
3631
late AnimationController controller;
3732

3833
@override
3934
void initState() {
4035
controller = AnimationController(
36+
/// [AnimationController]s can be created with `vsync: this` because of
37+
/// [TickerProviderStateMixin].
4138
vsync: this,
4239
duration: const Duration(seconds: 5),
4340
)..addListener(() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
/// Flutter code sample for [LinearProgressIndicator].
6+
7+
import 'package:flutter/material.dart';
8+
9+
void main() => runApp(const ProgressIndicatorApp());
10+
11+
class ProgressIndicatorApp extends StatelessWidget {
12+
const ProgressIndicatorApp({super.key});
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
return MaterialApp(
17+
theme: ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4)),
18+
home: const ProgressIndicatorExample(),
19+
);
20+
}
21+
}
22+
23+
class ProgressIndicatorExample extends StatefulWidget {
24+
const ProgressIndicatorExample({super.key});
25+
26+
@override
27+
State<ProgressIndicatorExample> createState() => _ProgressIndicatorExampleState();
28+
}
29+
30+
class _ProgressIndicatorExampleState extends State<ProgressIndicatorExample>
31+
with TickerProviderStateMixin {
32+
late AnimationController controller;
33+
bool determinate = false;
34+
35+
@override
36+
void initState() {
37+
controller = AnimationController(
38+
/// [AnimationController]s can be created with `vsync: this` because of
39+
/// [TickerProviderStateMixin].
40+
vsync: this,
41+
duration: const Duration(seconds: 2),
42+
)..addListener(() {
43+
setState(() {});
44+
});
45+
controller.repeat();
46+
super.initState();
47+
}
48+
49+
@override
50+
void dispose() {
51+
controller.dispose();
52+
super.dispose();
53+
}
54+
55+
@override
56+
Widget build(BuildContext context) {
57+
return Scaffold(
58+
body: Padding(
59+
padding: const EdgeInsets.all(20.0),
60+
child: Column(
61+
mainAxisAlignment: MainAxisAlignment.center,
62+
children: <Widget>[
63+
const Text(
64+
'Linear progress indicator',
65+
style: TextStyle(fontSize: 20),
66+
),
67+
const SizedBox(height: 30),
68+
LinearProgressIndicator(
69+
value: controller.value,
70+
semanticsLabel: 'Linear progress indicator',
71+
),
72+
const SizedBox(height: 10),
73+
Row(
74+
children: <Widget>[
75+
Expanded(
76+
child: Text(
77+
'determinate Mode',
78+
style: Theme.of(context).textTheme.titleSmall,
79+
),
80+
),
81+
Switch(
82+
value: determinate,
83+
onChanged: (bool value) {
84+
setState(() {
85+
determinate = value;
86+
if (determinate) {
87+
controller.stop();
88+
} else {
89+
controller..forward(from: controller.value)..repeat();
90+
}
91+
});
92+
},
93+
),
94+
],
95+
),
96+
],
97+
),
98+
),
99+
);
100+
}
101+
}

examples/api/test/material/progress_indicator/circular_progress_indicator.0_test.dart

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@ import 'package:flutter_test/flutter_test.dart';
99
void main() {
1010
testWidgets('Finds CircularProgressIndicator', (WidgetTester tester) async {
1111
await tester.pumpWidget(
12-
const example.MyApp(),
12+
const example.ProgressIndicatorApp(),
1313
);
14+
1415
expect(
1516
find.bySemanticsLabel('Circular progress indicator'),
1617
findsOneWidget,
1718
);
19+
20+
// Test if CircularProgressIndicator is animating.
21+
await tester.pump(const Duration(seconds: 2));
22+
expect(tester.hasRunningAnimations, isTrue);
1823
});
1924
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter_api_samples/material/progress_indicator/circular_progress_indicator.1.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('Finds CircularProgressIndicator', (WidgetTester tester) async {
12+
await tester.pumpWidget(
13+
const example.ProgressIndicatorApp(),
14+
);
15+
16+
expect(
17+
find.bySemanticsLabel('Circular progress indicator').first,
18+
findsOneWidget,
19+
);
20+
21+
// Test if CircularProgressIndicator is animating.
22+
expect(tester.hasRunningAnimations, isTrue);
23+
24+
await tester.pump(const Duration(seconds: 1));
25+
expect(tester.hasRunningAnimations, isTrue);
26+
27+
// Test determinate mode button.
28+
await tester.tap(find.byType(Switch));
29+
await tester.pumpAndSettle();
30+
expect(tester.hasRunningAnimations, isFalse);
31+
32+
await tester.tap(find.byType(Switch));
33+
await tester.pump(const Duration(seconds: 1));
34+
expect(tester.hasRunningAnimations, isTrue);
35+
});
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter_api_samples/material/progress_indicator/linear_progress_indicator.0.dart'
6+
as example;
7+
import 'package:flutter_test/flutter_test.dart';
8+
9+
void main() {
10+
testWidgets('Finds LinearProgressIndicator', (WidgetTester tester) async {
11+
await tester.pumpWidget(
12+
const example.ProgressIndicatorApp(),
13+
);
14+
15+
expect(
16+
find.bySemanticsLabel('Linear progress indicator'),
17+
findsOneWidget,
18+
);
19+
20+
// Test if LinearProgressIndicator is animating.
21+
await tester.pump(const Duration(seconds: 2));
22+
expect(tester.hasRunningAnimations, isTrue);
23+
});
24+
}

0 commit comments

Comments
 (0)