Skip to content

Commit 8815f60

Browse files
authored
Add AnimatedIcons previews and examples (#113700)
1 parent 9bdd50a commit 8815f60

File tree

7 files changed

+283
-11
lines changed

7 files changed

+283
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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 [AnimatedIcon].
6+
7+
import 'package:flutter/material.dart';
8+
9+
void main() {
10+
runApp(const AnimatedIconApp());
11+
}
12+
13+
class AnimatedIconApp extends StatelessWidget {
14+
const AnimatedIconApp({super.key});
15+
16+
@override
17+
Widget build(BuildContext context) {
18+
return MaterialApp(
19+
theme: ThemeData(
20+
colorSchemeSeed: const Color(0xff6750a4),
21+
useMaterial3: true,
22+
),
23+
home: const Scaffold(
24+
body: AnimatedIconExample(),
25+
),
26+
);
27+
}
28+
}
29+
30+
class AnimatedIconExample extends StatefulWidget {
31+
const AnimatedIconExample({super.key});
32+
33+
@override
34+
State<AnimatedIconExample> createState() => _AnimatedIconExampleState();
35+
}
36+
37+
class _AnimatedIconExampleState extends State<AnimatedIconExample> with SingleTickerProviderStateMixin {
38+
late AnimationController controller;
39+
late Animation<double> animation;
40+
41+
@override
42+
void initState() {
43+
super.initState();
44+
controller = AnimationController(
45+
vsync: this,
46+
duration: const Duration(seconds: 2),
47+
)..forward()
48+
..repeat(reverse: true);
49+
animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
50+
}
51+
52+
@override
53+
void dispose() {
54+
controller.dispose();
55+
super.dispose();
56+
}
57+
58+
@override
59+
Widget build(BuildContext context) {
60+
return Scaffold(
61+
body: Center(
62+
child: AnimatedIcon(
63+
icon: AnimatedIcons.menu_arrow,
64+
progress: animation,
65+
size: 72.0,
66+
semanticLabel: 'Show menu',
67+
),
68+
),
69+
);
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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 [AnimatedIcon].
6+
7+
import 'package:flutter/material.dart';
8+
9+
final Map<String, AnimatedIconData> iconsList = <String, AnimatedIconData>{
10+
'add_event': AnimatedIcons.add_event,
11+
'arrow_menu': AnimatedIcons.arrow_menu,
12+
'close_menu': AnimatedIcons.close_menu,
13+
'ellipsis_search': AnimatedIcons.ellipsis_search,
14+
'event_add': AnimatedIcons.event_add,
15+
'home_menu': AnimatedIcons.home_menu,
16+
'list_view': AnimatedIcons.list_view,
17+
'menu_arrow': AnimatedIcons.menu_arrow,
18+
'menu_close': AnimatedIcons.menu_close,
19+
'menu_home': AnimatedIcons.menu_home,
20+
'pause_play': AnimatedIcons.pause_play,
21+
'play_pause': AnimatedIcons.play_pause,
22+
'search_ellipsis': AnimatedIcons.search_ellipsis,
23+
'view_list': AnimatedIcons.view_list,
24+
};
25+
26+
void main() {
27+
runApp(const AnimatedIconApp());
28+
}
29+
30+
class AnimatedIconApp extends StatelessWidget {
31+
const AnimatedIconApp({super.key});
32+
33+
@override
34+
Widget build(BuildContext context) {
35+
return MaterialApp(
36+
theme: ThemeData(
37+
colorSchemeSeed: const Color(0xff6750a4),
38+
useMaterial3: true,
39+
),
40+
home: const Scaffold(
41+
body: AnimatedIconExample(),
42+
),
43+
);
44+
}
45+
}
46+
47+
class AnimatedIconExample extends StatefulWidget {
48+
const AnimatedIconExample({super.key});
49+
50+
@override
51+
State<AnimatedIconExample> createState() => _AnimatedIconExampleState();
52+
}
53+
54+
class _AnimatedIconExampleState extends State<AnimatedIconExample> with SingleTickerProviderStateMixin {
55+
late AnimationController controller;
56+
late Animation<double> animation;
57+
58+
@override
59+
void initState() {
60+
super.initState();
61+
controller = AnimationController(
62+
vsync: this,
63+
duration: const Duration(seconds: 2),
64+
)..forward()
65+
..repeat(reverse: true);
66+
animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
67+
}
68+
69+
@override
70+
void dispose() {
71+
controller.dispose();
72+
super.dispose();
73+
}
74+
75+
@override
76+
Widget build(BuildContext context) {
77+
return Scaffold(
78+
body: GridView(
79+
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
80+
crossAxisCount: 4,
81+
),
82+
children: iconsList.entries.map((MapEntry<String, AnimatedIconData> entry) {
83+
return Card(
84+
child: Center(
85+
child: Column(
86+
mainAxisAlignment: MainAxisAlignment.center,
87+
children: <Widget>[
88+
AnimatedIcon(
89+
icon: entry.value,
90+
progress: animation,
91+
size: 72.0,
92+
semanticLabel: entry.key,
93+
),
94+
const SizedBox(height: 8.0),
95+
Text(entry.key),
96+
],
97+
),
98+
),
99+
);
100+
}).toList(),
101+
),
102+
);
103+
}
104+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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/animated_icon/animated_icon.0.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('AnimatedIcon animates', (WidgetTester tester) async {
12+
await tester.pumpWidget(
13+
const example.AnimatedIconApp(),
14+
);
15+
16+
// Test the AnimatedIcon size.
17+
final Size iconSize = tester.getSize(find.byType(AnimatedIcon));
18+
expect(iconSize.width, 72.0);
19+
expect(iconSize.height, 72.0);
20+
21+
// Check if AnimatedIcon is animating.
22+
await tester.pump(const Duration(milliseconds: 500));
23+
AnimatedIcon animatedIcon = tester.widget(find.byType(AnimatedIcon));
24+
expect(animatedIcon.progress.value, 0.25);
25+
26+
// Check if animation is completed.
27+
await tester.pump(const Duration(milliseconds: 1500));
28+
animatedIcon = tester.widget(find.byType(AnimatedIcon));
29+
expect(animatedIcon.progress.value, 1.0);
30+
});
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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/animated_icon/animated_icon.1.dart'
7+
as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('Show all the animated icons', (WidgetTester tester) async {
12+
await tester.pumpWidget(
13+
const example.AnimatedIconApp(),
14+
);
15+
16+
// Check if the total number of AnimatedIcons matches the icons list.
17+
expect(find.byType(AnimatedIcon, skipOffstage: false), findsNWidgets(example.iconsList.length));
18+
19+
// Test the AnimatedIcon size.
20+
final Size iconSize = tester.getSize(find.byType(AnimatedIcon).first);
21+
expect(iconSize.width, 72.0);
22+
expect(iconSize.height, 72.0);
23+
24+
// Check if AnimatedIcon is animating.
25+
await tester.pump(const Duration(milliseconds: 500));
26+
AnimatedIcon animatedIcon = tester.widget(find.byType(AnimatedIcon).first);
27+
expect(animatedIcon.progress.value, 0.25);
28+
29+
// Check if animation is completed.
30+
await tester.pump(const Duration(milliseconds: 1500));
31+
animatedIcon = tester.widget(find.byType(AnimatedIcon).first);
32+
expect(animatedIcon.progress.value, 1.0);
33+
});
34+
}

packages/flutter/lib/src/material/animated_icons/animated_icons.dart

+14-11
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,29 @@ part of material_animated_icons;
99
// See: https://github.com/flutter/flutter/issues/1831 for details regarding
1010
// generic vector graphics support in Flutter.
1111

12-
// Examples can assume:
13-
// late AnimationController controller;
14-
1512
/// Shows an animated icon at a given animation [progress].
1613
///
1714
/// The available icons are specified in [AnimatedIcons].
1815
///
1916
/// {@youtube 560 315 https://www.youtube.com/watch?v=pJcbh8pbvJs}
2017
///
21-
/// {@tool snippet}
18+
/// {@tool dartpad}
19+
/// This example shows how to create an animated icon. The icon is animated
20+
/// forward and reverse in a loop.
2221
///
23-
/// ```dart
24-
/// AnimatedIcon(
25-
/// icon: AnimatedIcons.menu_arrow,
26-
/// progress: controller,
27-
/// semanticLabel: 'Show menu',
28-
/// )
29-
/// ```
22+
/// ** See code in examples/api/lib/material/animated_icon/animated_icon.0.dart **
3023
/// {@end-tool}
3124
///
25+
/// {@tool dartpad}
26+
/// This example showcases all the available [AnimatedIcons] in a [GridView].
27+
/// The icons are animated forward and reverse in a loop.
28+
///
29+
/// ** See code in examples/api/lib/material/animated_icon/animated_icon.1.dart **
30+
/// {@end-tool}
31+
///
32+
/// See also:
33+
///
34+
/// * [Icons], for the list of available static Material Icons.
3235
class AnimatedIcon extends StatelessWidget {
3336
/// Creates an AnimatedIcon.
3437
///

packages/flutter/lib/src/material/animated_icons/animated_icons_data.dart

+28
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,73 @@ part of material_animated_icons;
1616
abstract class AnimatedIcons {
1717

1818
/// The Material Design add to event icon animation.
19+
///
20+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/add_event.mp4}
1921
static const AnimatedIconData add_event = _$add_event;
2022

2123
/// The Material Design arrow to menu icon animation.
24+
///
25+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/arrow_menu.mp4}
2226
static const AnimatedIconData arrow_menu = _$arrow_menu;
2327

2428
/// The Material Design close to menu icon animation.
29+
///
30+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/close_menu.mp4}
2531
static const AnimatedIconData close_menu = _$close_menu;
2632

2733
/// The Material Design ellipsis to search icon animation.
34+
///
35+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/ellipsis_search.mp4}
2836
static const AnimatedIconData ellipsis_search = _$ellipsis_search;
2937

3038
/// The Material Design event to add icon animation.
39+
///
40+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/event_add.mp4}
3141
static const AnimatedIconData event_add = _$event_add;
3242

3343
/// The Material Design home to menu icon animation.
44+
///
45+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/home_menu.mp4}
3446
static const AnimatedIconData home_menu = _$home_menu;
3547

3648
/// The Material Design list to view icon animation.
49+
///
50+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/list_view.mp4}
3751
static const AnimatedIconData list_view = _$list_view;
3852

3953
/// The Material Design menu to arrow icon animation.
54+
///
55+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/menu_arrow.mp4}
4056
static const AnimatedIconData menu_arrow = _$menu_arrow;
4157

4258
/// The Material Design menu to close icon animation.
59+
///
60+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/menu_close.mp4}
4361
static const AnimatedIconData menu_close = _$menu_close;
4462

4563
/// The Material Design menu to home icon animation.
64+
///
65+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/menu_home.mp4}
4666
static const AnimatedIconData menu_home = _$menu_home;
4767

4868
/// The Material Design pause to play icon animation.
69+
///
70+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/pause_play.mp4}
4971
static const AnimatedIconData pause_play = _$pause_play;
5072

5173
/// The Material Design play to pause icon animation.
74+
///
75+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/play_pause.mp4}
5276
static const AnimatedIconData play_pause = _$play_pause;
5377

5478
/// The Material Design search to ellipsis icon animation.
79+
///
80+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/search_ellipsis.mp4}
5581
static const AnimatedIconData search_ellipsis = _$search_ellipsis;
5682

5783
/// The Material Design view to list icon animation.
84+
///
85+
/// {@animation 72 72 https://flutter.github.io/assets-for-api-docs/assets/widgets/view_list.mp4}
5886
static const AnimatedIconData view_list = _$view_list;
5987
}
6088

packages/flutter/lib/src/material/icons.dart

+1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class PlatformAdaptiveIcons implements Icons {
148148
/// * [Icon]
149149
/// * [IconButton]
150150
/// * <https://material.io/resources/icons>
151+
/// * [AnimatedIcons], for the list of available animated Material Icons.
151152
class Icons {
152153
// This class is not meant to be instantiated or extended; this constructor
153154
// prevents instantiation and extension.

0 commit comments

Comments
 (0)