Flutter:同时使用平移和缩放手势吗?

时间:2020-04-28 20:45:10

标签: android flutter dart gesturedetector

我正在创建带有颤动的绘图画布,我想同时使用比例(用于缩放,平移和旋转)和平移(用于用手指绘制)手势,但是由于比例是Pan的超集,所以颤动不允许这样做。有什么解决方法吗?

我试图创建自己的自定义手势识别器,以检测屏幕上的指针数量,以便如果两个指针在短时间间隔(比如说1秒)内与屏幕接触,则秤将接管,否则摇摄开始使用触摸屏幕的第一个指针。我正在使用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) {}

}

2 个答案:

答案 0 :(得分:1)

您要做的是将 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
            },

希望这会有所帮助。我也花了一些时间才弄明白。

答案 1 :(得分:0)

使用“监听器”小部件来监听指针事件,然后处理指针事件以根据需要检测缩放和平移手势。

  • 1个指针(在短时间内上下移动)=>点按
  • 1个指针(长时间间隔上下)=>双击
  • 1个指针(向下移动)=>平移
  • 2个指针=>缩放并旋转

您可以使用gesture_x_detector一起获得全部支持手势(点击,双击,缩放,旋转,长按...)。