英文:
How to test an AnimatedIcon in Flutter
问题
- 有没有类似于
finder.byIcon()
的方法,但接受AnimatedIconData
而不是IconData
? - 如何验证动画是否正在进行?
英文:
I want to do a test that allows me to verify if my widget is showing the AnimatedIcon
that I provide, as well as to know if the animation is working (changing the icon in an animated way), the problem is that I can't find the way to do it.
- Is there a method similar to
finder.byIcon()
, but that acceptsAnimatedIconData
instead ofIconData
? - How to verify that the animation is happening?
答案1
得分: 2
- 获取
AnimatedIconData
的查找器
要获取 AnimatedIconData
的查找器,请使用以下方法,使用 find.byWidgetPredicate(假设要搜索的 AnimatedIconData
是 AnimatedIcons.menu_arrow
):
final animatedIconFinder = find.byWidgetPredicate((widget) =>
widget is AnimatedIcon && widget.icon == AnimatedIcons.menu_arrow);
- 验证动画是否正在进行
要验证动画是否正在进行,请检查 AnimatedIcon 小部件的 progress 属性的值。
假设动画发生在屏幕上的一个浮动操作按钮被点击之后,下面的代码示例显示了如何验证在按钮被点击后 AnimatedIcon
是否进行动画。
// 获取 [AnimatedIcon] 小部件
final animatedIconWidget = tester.widget(animatedIconFinder) as AnimatedIcon;
final animatedIconProgress = animatedIconWidget.progress.value;
// 验证 [AnimatedIcon] 是否不在进行动画
expect(animatedIconProgress, 0);
// 查找 [FloatingActionButton]
final floatingActionButtonFinder =
find.widgetWithIcon(FloatingActionButton, Icons.change_circle);
// 点击 [FloatingActionButton]
await tester.tap(floatingActionButtonFinder);
await tester.pumpAndSettle();
final updatedAnimatedIconProgress = animatedIconWidget.progress.value;
// 验证 [AnimatedIcon] 已完成其动画
expect(updatedAnimatedIconProgress, 1);
使用自定义查找器
要使您的查找器更简洁并类似于 find.byIcon,请执行以下操作:
-
通过扩展 MatchFinder 创建自定义查找器,并在
matches
方法中添加匹配逻辑(这是 find.byIcon 的修改实现)。class _WidgetAnimatedIconFinder extends MatchFinder { _WidgetAnimatedIconFinder(this.icon, {super.skipOffstage}); final AnimatedIconData icon; @override String get description => 'icon "$icon"'; @override bool matches(Element candidate) { final Widget widget = candidate.widget; return widget is AnimatedIcon && widget.icon == icon; } }
-
创建 CommonFinders 类的扩展,并添加一个
byAnimatedIcon
方法,该方法使用步骤1中创建的自定义查找器。CommonFinders 类由 flutter_test 包提供,find 常量(如find.byIcon
)是CommonFinders
的实例。extension CustomFindersExtension on CommonFinders { Finder byAnimatedIcon(AnimatedIconData icon) => _WidgetAnimatedIconFinder(icon); }
-
使用
find.byAnimatedIcon
来查找要搜索的AnimatedIconData
。用以下代码替换使用
find.byWidgetPredicate
的查找器:final animatedIconFinder = find.byAnimatedIcon(AnimatedIcons.menu_arrow);
英文:
1. Finder for AnimatedIconData
To get a finder for AnimatedIconData
, use the find.byWidgetPredicate method like below (assuming the AnimatedIconData
being searched for is AnimatedIcons.menu_arrow
):
final animatedIconFinder = find.byWidgetPredicate((widget) =>
widget is AnimatedIcon && widget.icon == AnimatedIcons.menu_arrow);
2. Verification that the animation is happening
To verify that the animation is happening, check the value of the AnimatedIcon widget's progress property.
Assuming the animation happens after a floating action button on the screen is tapped, the code sample below shows how to verify that the AnimatedIcon
animates after the button is tapped.
// Gets the [AnimatedIcon] widget
final animatedIconWidget = tester.widget(animatedIconFinder) as AnimatedIcon;
final animatedIconProgress = animatedIconWidget.progress.value;
// Verifies that [AnimatedIcon] is not animating
expect(animatedIconProgress, 0);
// Finds [FloatingActionButton]
final floatingActionButtonFinder =
find.widgetWithIcon(FloatingActionButton, Icons.change_circle);
// Taps [FloatingActionButton]
await tester.tap(floatingActionButtonFinder);
await tester.pumpAndSettle();
final updatedAnimatedIconProgress = animatedIconWidget.progress.value;
// Verifies that the [AnimatedIcon] has completed its animation
expect(updatedAnimatedIconProgress, 1);
Using a Custom Finder
To make your finder more concise and similar to find.byIcon, do the following:
-
Create a custom Finder by extending MatchFinder and add the matching logic in the
matches
method (This is a modification of the find.byIcon implementation).class _WidgetAnimatedIconFinder extends MatchFinder { _WidgetAnimatedIconFinder(this.icon, {super.skipOffstage}); final AnimatedIconData icon; @override String get description => 'icon "$icon"'; @override bool matches(Element candidate) { final Widget widget = candidate.widget; return widget is AnimatedIcon && widget.icon == icon; } }
-
Create an extension on the CommonFinders class and add a
byAnimatedIcon
method that uses the custom Finder created in step 1. The CommonFinders class is provided by the flutter_test package and the find constant (as infind.byIcon
) is an instance ofCommonFinders
.extension CustomFindersExtension on CommonFinders { Finder byAnimatedIcon(AnimatedIconData icon) => _WidgetAnimatedIconFinder(icon); }
-
Use
find.byAnimatedIcon
to find the AnimatedIcon by supplying theAnimatedIconData
being searched for.Replace the
Finder
usingfind.byWidgetPredicate
with this below:final animatedIconFinder = find.byAnimatedIcon(AnimatedIcons.menu_arrow);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论