如何在 Flutter 小部件测试中执行缩放(捏缩放)多指手势?

Posted

技术标签:

【中文标题】如何在 Flutter 小部件测试中执行缩放(捏缩放)多指手势?【英文标题】:How can I perform a scale (pinch to zoom) multi finger gesture in Flutter's widget tests? 【发布时间】:2020-06-20 15:56:28 【问题描述】:

我正在为一个小部件编写小部件测试,该小部件通过使用 onScaleUpdate 属性回调实例化 GestureDetector 来处理用户对其执行缩放/缩放手势时的操作。我知道如何在小部件测试中执行拖动、点击和长按,但我找不到在小部件测试中执行缩放手势的方法。

我尝试了几种方法,例如在相反方向上同时拖动:

final myWidget = find.byKey(const Key("myWidget"));
await tester.drag(myWidget, Offset(100, 0));
await tester.drag(myWidget, Offset(-100, 0));

但拖动不能同时发生,框架会强制我 await 直到拖动完成,然后再执行第二次拖动。

有没有办法在小部件测试中执行缩放/捏拉缩放/多指手势?

【问题讨论】:

【参考方案1】:

您可以使用WidgetTester 的createGesture() 或startGesture() 方法创建两个或多个触摸并控制它们。这是一个例子:

    final widgetFinder = find.byKey(ValueKey('Scalable widget'));
    final center = tester.getCenter(widgetFinder);
    
    // create two touches:
    final touch1 = await tester.startGesture(center.translate(-10, 0));
    final touch2 = await tester.startGesture(center.translate(10, 0));

    // zoom in:
    await touch1.moveBy(Offset(-100, 0));
    await touch2.moveBy(Offset(100, 0));
    await tester.pump();
    
    // zoom out:
    await touch1.moveBy(Offset(10, 0));
    await touch2.moveBy(Offset(-10, 0));
    await tester.pump();
    
    // cancel touches:
    await touch1.cancel();
    await touch2.cancel();

【讨论】:

【参考方案2】:

你可以这样做:

// Create the finder
final interactiveViewFinder = find.byType(InteractiveViewer);

// Get the center      
final center = tester.getCenter(interactiveViewFinder);

// Zoom in:
final Offset scaleStart1 = center;
final Offset scaleStart2 = Offset(center.dx + 10.0, center.dy);
final Offset scaleEnd1 = Offset(center.dx - 10.0, center.dy);
final Offset scaleEnd2 = Offset(center.dx + 10.0, center.dy);
final TestGesture gesture = await tester.createGesture();
final TestGesture gesture2 = await tester.createGesture();
await gesture.down(scaleStart1);
await gesture2.down(scaleStart2);
await tester.pump();
await gesture.moveTo(scaleEnd1);
await gesture2.moveTo(scaleEnd2);
await tester.pump();
await gesture.up();
await gesture2.up();
await tester.pumpAndSettle();

来源:Flutter 自己对InteractiveViewer 的单元测试:https://github.com/flutter/flutter/blob/7d368dcf0c00b45fef5b02c5cccb8aa5306234ba/packages/flutter/test/widgets/interactive_viewer_test.dart#L49

【讨论】:

以上是关于如何在 Flutter 小部件测试中执行缩放(捏缩放)多指手势?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 小部件测试中等待未来完成?

如何在 Flutter 小部件中测试回调函数

Flutter - 如何测试小部件中的抽屉测试?

Flutter - 如何在小部件测试中选择 DropdownButton 项

在 Flutter 小部件测试中,如何验证字段验证错误消息?

如何在 Flutter 中测试图像小部件的源路径