android - Flutter:同时使用 Pan 和 Scale 手势?

标签 android flutter dart gesturedetector

我正在创建一个带有 flutter 的绘图 Canvas ,我想同时使用缩放(用于缩放、平移和旋转)和平移(用于用手指绘图)手势,但 flutter 不允许这样做,因为缩放是平移的超集。有什么解决方法吗?

我尝试创建自己的自定义手势识别器来检测屏幕上的指针数量,以便如果两个指针在短时间内(比如说 1 秒)与屏幕接触,则 Scale 接管,否则 pan 开始使用第一个触摸屏幕的指针。我正在使用 matrix_gesture_detector用于缩放部分的包。

这是我的自定义手势识别器代码

class ScaleAndPanRecognizer extends OneSequenceGestureRecognizer {
  var manager = GestureArenaManager();
  final Function onPanDown;
  final Function onPanUpdate;
  final Function onPanEnd;
  ScaleAndPanRecognizer({
    @required this.onPanDown,
    @required this.onPanUpdate,
    @required this.onPanEnd,
  });

  int numPointers = 0;
  int timeFrame = 1;
  int pointer1;
  int pointer2;
  var time1;
  var time2;
  var position1;

  @override
  void addPointer(PointerDownEvent event) {
    print(numPointers);
    if (numPointers == 0) {
      pointer1 = event.pointer;
      print(pointer1);
      position1 = event.localPosition;
      manager.hold(pointer1); //hold the assignment for this pointer for now
      startTrackingPointer(pointer1);

      numPointers += 1;
      time1 = DateTime.now();
    } else if (numPointers == 1) {
      pointer2 = event.pointer;
      print(pointer2);
      resolvePointer(pointer2, GestureDisposition.rejected);
      time2 = DateTime.now();
      var diff = time2.difference(time1);
      print(diff);
      if (diff <= Duration(seconds: timeFrame)) {
        manager.release(pointer1);
        resolvePointer(pointer1, GestureDisposition.rejected);
      } else {
        resolvePointer(pointer1, GestureDisposition.accepted);
        manager.release(pointer1);
        onPanDown(position1);
      }
      numPointers = 0;
    }
  }

  @override
  void handleEvent(PointerEvent event) {
    if (event is PointerMoveEvent) {
      onPanUpdate(event.localPosition);
    }
    if (event is PointerUpEvent) {
      onPanEnd();
      stopTrackingPointer(event.pointer);
    }
  }

  @override
  String get debugDescription => 'only one pointer recognizer';

  @override
  void didStopTrackingLastPointer(int pointer) {}

}

最佳答案

你要做的是替换onPanUpdate, onPanEnd...onScaleUpdate, onScaleEnd... .然后只是代替details.globalPosition 使用 details.focalPoint .您将获得与 Pan 相同的行为,而且您现在可以访问 details.scaledetails.rotation .这是一个例子。
前:

onPanUpdate: (DragUpdateDetails details){
              newPosition = details.globalPosition;
              //scale and rotation missing in pan
            },
后:
onScaleUpdate: (ScaleUpdateDetails details){
              newPosition = details.focalPoint;
              newRotation = details.rotation;
              newScale = details.scale;
              //scale and rotation now available
            },
希望这可以帮助。我也花了一些时间才弄清楚。

关于android - Flutter:同时使用 Pan 和 Scale 手势?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61489657/

相关文章:

android - Xamarin.Forms 获取 Mono.Linker.MarkException : Error processing method when compiling in release mode

java - Flutter:PlatformException(错误,尝试调用虚拟方法 'java.lang.Object android.app.Activity.getSystemService(java.lang.String)'

flutter - 在 Android Studio 中的项目面板中隐藏不必要的文件夹和文件

flutter - 将 Flutter 动画直接渲染到视频

dart - 实现代理服务器

java - DecimalFormat 模式问题

android - 移动原生应用程序中的字体使用

flutter - 在构建函数之外使用BuildContext

android - flutter 任务 ':app:checkDebugAarMetadata' 执行失败

flutter - 如何使Flutter提供程序从工厂提供者notifyListeners()?