Skip to content

Commit

Permalink
Add AnimatedIcons previews and examples (#113700)
Browse files Browse the repository at this point in the history
  • Loading branch information
TahaTesser committed Oct 19, 2022
1 parent 9bdd50a commit 8815f60
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 11 deletions.
71 changes: 71 additions & 0 deletions examples/api/lib/material/animated_icon/animated_icon.0.dart
@@ -0,0 +1,71 @@
// 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.

/// Flutter code sample for [AnimatedIcon].
import 'package:flutter/material.dart';

void main() {
runApp(const AnimatedIconApp());
}

class AnimatedIconApp extends StatelessWidget {
const AnimatedIconApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorSchemeSeed: const Color(0xff6750a4),
useMaterial3: true,
),
home: const Scaffold(
body: AnimatedIconExample(),
),
);
}
}

class AnimatedIconExample extends StatefulWidget {
const AnimatedIconExample({super.key});

@override
State<AnimatedIconExample> createState() => _AnimatedIconExampleState();
}

class _AnimatedIconExampleState extends State<AnimatedIconExample> with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation<double> animation;

@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..forward()
..repeat(reverse: true);
animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
}

@override
void dispose() {
controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: animation,
size: 72.0,
semanticLabel: 'Show menu',
),
),
);
}
}
104 changes: 104 additions & 0 deletions examples/api/lib/material/animated_icon/animated_icon.1.dart
@@ -0,0 +1,104 @@
// 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.

/// Flutter code sample for [AnimatedIcon].
import 'package:flutter/material.dart';

final Map<String, AnimatedIconData> iconsList = <String, AnimatedIconData>{
'add_event': AnimatedIcons.add_event,
'arrow_menu': AnimatedIcons.arrow_menu,
'close_menu': AnimatedIcons.close_menu,
'ellipsis_search': AnimatedIcons.ellipsis_search,
'event_add': AnimatedIcons.event_add,
'home_menu': AnimatedIcons.home_menu,
'list_view': AnimatedIcons.list_view,
'menu_arrow': AnimatedIcons.menu_arrow,
'menu_close': AnimatedIcons.menu_close,
'menu_home': AnimatedIcons.menu_home,
'pause_play': AnimatedIcons.pause_play,
'play_pause': AnimatedIcons.play_pause,
'search_ellipsis': AnimatedIcons.search_ellipsis,
'view_list': AnimatedIcons.view_list,
};

void main() {
runApp(const AnimatedIconApp());
}

class AnimatedIconApp extends StatelessWidget {
const AnimatedIconApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorSchemeSeed: const Color(0xff6750a4),
useMaterial3: true,
),
home: const Scaffold(
body: AnimatedIconExample(),
),
);
}
}

class AnimatedIconExample extends StatefulWidget {
const AnimatedIconExample({super.key});

@override
State<AnimatedIconExample> createState() => _AnimatedIconExampleState();
}

class _AnimatedIconExampleState extends State<AnimatedIconExample> with SingleTickerProviderStateMixin {
late AnimationController controller;
late Animation<double> animation;

@override
void initState() {
super.initState();
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 2),
)..forward()
..repeat(reverse: true);
animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
}

@override
void dispose() {
controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
children: iconsList.entries.map((MapEntry<String, AnimatedIconData> entry) {
return Card(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
AnimatedIcon(
icon: entry.value,
progress: animation,
size: 72.0,
semanticLabel: entry.key,
),
const SizedBox(height: 8.0),
Text(entry.key),
],
),
),
);
}).toList(),
),
);
}
}
31 changes: 31 additions & 0 deletions examples/api/test/material/animated_icon/animated_icon.0_test.dart
@@ -0,0 +1,31 @@
// 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 'package:flutter/material.dart';
import 'package:flutter_api_samples/material/animated_icon/animated_icon.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('AnimatedIcon animates', (WidgetTester tester) async {
await tester.pumpWidget(
const example.AnimatedIconApp(),
);

// Test the AnimatedIcon size.
final Size iconSize = tester.getSize(find.byType(AnimatedIcon));
expect(iconSize.width, 72.0);
expect(iconSize.height, 72.0);

// Check if AnimatedIcon is animating.
await tester.pump(const Duration(milliseconds: 500));
AnimatedIcon animatedIcon = tester.widget(find.byType(AnimatedIcon));
expect(animatedIcon.progress.value, 0.25);

// Check if animation is completed.
await tester.pump(const Duration(milliseconds: 1500));
animatedIcon = tester.widget(find.byType(AnimatedIcon));
expect(animatedIcon.progress.value, 1.0);
});
}
34 changes: 34 additions & 0 deletions examples/api/test/material/animated_icon/animated_icon.1_test.dart
@@ -0,0 +1,34 @@
// 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 'package:flutter/material.dart';
import 'package:flutter_api_samples/material/animated_icon/animated_icon.1.dart'
as example;
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('Show all the animated icons', (WidgetTester tester) async {
await tester.pumpWidget(
const example.AnimatedIconApp(),
);

// Check if the total number of AnimatedIcons matches the icons list.
expect(find.byType(AnimatedIcon, skipOffstage: false), findsNWidgets(example.iconsList.length));

// Test the AnimatedIcon size.
final Size iconSize = tester.getSize(find.byType(AnimatedIcon).first);
expect(iconSize.width, 72.0);
expect(iconSize.height, 72.0);

// Check if AnimatedIcon is animating.
await tester.pump(const Duration(milliseconds: 500));
AnimatedIcon animatedIcon = tester.widget(find.byType(AnimatedIcon).first);
expect(animatedIcon.progress.value, 0.25);

// Check if animation is completed.
await tester.pump(const Duration(milliseconds: 1500));
animatedIcon = tester.widget(find.byType(AnimatedIcon).first);
expect(animatedIcon.progress.value, 1.0);
});
}
Expand Up @@ -9,26 +9,29 @@ part of material_animated_icons;
// See: https://github.com/flutter/flutter/issues/1831 for details regarding
// generic vector graphics support in Flutter.

// Examples can assume:
// late AnimationController controller;

/// Shows an animated icon at a given animation [progress].
///
/// The available icons are specified in [AnimatedIcons].
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=pJcbh8pbvJs}
///
/// {@tool snippet}
/// {@tool dartpad}
/// This example shows how to create an animated icon. The icon is animated
/// forward and reverse in a loop.
///
/// ```dart
/// AnimatedIcon(
/// icon: AnimatedIcons.menu_arrow,
/// progress: controller,
/// semanticLabel: 'Show menu',
/// )
/// ```
/// ** See code in examples/api/lib/material/animated_icon/animated_icon.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This example showcases all the available [AnimatedIcons] in a [GridView].
/// The icons are animated forward and reverse in a loop.
///
/// ** See code in examples/api/lib/material/animated_icon/animated_icon.1.dart **
/// {@end-tool}
///
/// See also:
///
/// * [Icons], for the list of available static Material Icons.
class AnimatedIcon extends StatelessWidget {
/// Creates an AnimatedIcon.
///
Expand Down
Expand Up @@ -16,45 +16,73 @@ part of material_animated_icons;
abstract class AnimatedIcons {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Expand Down
1 change: 1 addition & 0 deletions packages/flutter/lib/src/material/icons.dart
Expand Up @@ -148,6 +148,7 @@ class PlatformAdaptiveIcons implements Icons {
/// * [Icon]
/// * [IconButton]
/// * <https://material.io/resources/icons>
/// * [AnimatedIcons], for the list of available animated Material Icons.
class Icons {
// This class is not meant to be instantiated or extended; this constructor
// prevents instantiation and extension.
Expand Down

0 comments on commit 8815f60

Please sign in to comment.