Flutter Zoom在真实设备上无法正常工作

时间:2020-05-03 12:56:26

标签: flutter dart

我正在尝试在带有instagram的图像上实现抖动功能,我做到了,并且在模拟器(ios / android)上运行良好,但是在实际设备上,我遇到了一个问题,有时无法进行缩放操作,工作中,我必须将两根手指放在图像上一秒钟,然后开始捏一下,如果我快速完成操作,则尝试向下滚动

Zoom.dart

disp2

当我调用zoom.dart时

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:vector_math/vector_math_64.dart';

//
// Transform widget enables the overlay to be updated dynamically
//
class TransformWidget extends StatefulWidget {
  final Widget child;
  final Matrix4 matrix;

  const TransformWidget({Key key, @required this.child, @required this.matrix})
      : assert(child != null),
        super(key: key);

  @override
  _TransformWidgetState createState() => _TransformWidgetState();
}

class _TransformWidgetState extends State<TransformWidget> {
  Matrix4 _matrix = Matrix4.identity();

  @override
  Widget build(BuildContext context) {
    return Transform(
      transform: (widget.matrix * _matrix),
      child: widget.child,
    );
  }

  void setMatrix(Matrix4 matrix) {
    setState(() {
      _matrix = matrix;
    });
  }
}

//
// ZoomOverlay enables a image to have full screen drag, pinch and zoom
//
class ZoomOverlay extends StatefulWidget {
  final Widget child;
  final bool twoTouchOnly;

  const ZoomOverlay({
    Key key,
    @required this.twoTouchOnly,
    @required this.child,
  })  : assert(child != null),
        super(key: key);

  @override
  ZoomOverlayState createState() => ZoomOverlayState();
}

class ZoomOverlayState extends State<ZoomOverlay>
    with TickerProviderStateMixin {
  Matrix4 _matrix = Matrix4.identity();
  Offset _startFocalPoint;
  Animation<Matrix4> _animationReset;
  AnimationController _controllerReset;
  OverlayEntry _overlayEntry;
  bool isZooming = false;
  int _touchCount = 0;
  Matrix4 _transformMatrix = Matrix4.identity();

  final GlobalKey<_TransformWidgetState> _transformWidget =
      GlobalKey<_TransformWidgetState>();

  @override
  void initState() {
    super.initState();

    _controllerReset =
        AnimationController(vsync: this, duration: Duration(milliseconds: 100));

    _controllerReset.addListener(() {
      _transformWidget.currentState.setMatrix(_animationReset.value);
    });

    _controllerReset.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        hide();
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Listener(
        onPointerDown: _incrementEnter,
        onPointerUp: _incrementExit,
        child: GestureDetector(
            onScaleStart: (details) {
              onScaleStart(details, context);
            },
            onScaleUpdate: onScaleUpdate,
            onScaleEnd: onScaleEnd,
            child: Opacity(opacity: isZooming ? 0 : 1, child: widget.child)));
  }

  void onScaleStart(ScaleStartDetails details, BuildContext context) {
    if (widget.twoTouchOnly && _touchCount < 2) return;
    _startFocalPoint = details.focalPoint;
    _matrix = Matrix4.identity();
    // create an matrix of where the image is on the screen for the overlay
    RenderBox renderBox = context.findRenderObject();
    Offset position = renderBox.localToGlobal(Offset.zero);
    _transformMatrix =
        Matrix4.translation(Vector3(position.dx, position.dy, 0));

    show(context);

    setState(() {
      isZooming = true;
    });
  }

  void onScaleUpdate(ScaleUpdateDetails details) {
    if (!isZooming) return;

    Offset translationDelta = details.focalPoint - _startFocalPoint;

    Matrix4 translate = Matrix4.translation(
        Vector3(translationDelta.dx, translationDelta.dy, 0));

    RenderBox renderBox = context.findRenderObject();
    Offset focalPoint =
        renderBox.globalToLocal(details.focalPoint - translationDelta);

    var dx = (1 - details.scale) * focalPoint.dx;
    var dy = (1 - details.scale) * focalPoint.dy;

    Matrix4 scale = Matrix4(details.scale, 0, 0, 0, 0, details.scale, 0, 0, 0,
        0, 1, 0, dx, dy, 0, 1);

    _matrix = translate * scale;

    if (_transformWidget != null && _transformWidget.currentState != null) {
      _transformWidget.currentState.setMatrix(_matrix);
    }
  }

  void onScaleEnd(ScaleEndDetails details) {
    if (!isZooming) return;

    _animationReset = Matrix4Tween(begin: _matrix, end: Matrix4.identity())
        .animate(_controllerReset);
    _controllerReset.reset();
    _controllerReset.forward();
  }

  Widget _build(BuildContext context) {
    return IgnorePointer(
      child: Stack(
        children: [
          TransformWidget(
            key: _transformWidget,
            matrix: _transformMatrix,
            child: widget.child,
          )
        ],
      ),
    );
  }

  void show(BuildContext context) async {
    if (!isZooming) {
      OverlayState overlayState = Overlay.of(context);
      _overlayEntry = new OverlayEntry(builder: _build);
      overlayState.insert(_overlayEntry);
    }
  }

  void hide() async {
    setState(() {
      isZooming = false;
    });

    _overlayEntry.remove();
    _overlayEntry = null;
  }

  void _incrementEnter(PointerEvent details) {
    _touchCount++;
    print(_touchCount);
  }

  void _incrementExit(PointerEvent details) {
    _touchCount--;
        print(_touchCount);

  }
}

屏幕截图

Before Zoom

On Zoom

0 个答案:

没有答案