Flutter:将图像保持在屏幕边界内按比例和平移

Flutter: keep image within the screen borders on scale and pan

我正在尝试通过双击和缩放在图像上实现缩放 in\out,但我发现每当我缩放图像时 - 图像能够部分“走出”屏幕并且背景填充 space 左侧...(请参阅下面当前应用状态的屏幕截图)。我尝试包装一些其他小部件并更改图像的 fit 属性,但它没有产生任何结果。

我希望图像始终适合屏幕边界,尤其是在缩放时。我错过了什么?如何使图像在缩放或平移时不“滑动”到屏幕边界之外?

Screenshot of app's current state,其中空的space用黄色标示

我的代码:

  ///controllers and details variable for zoom on double tap
  final _transformationController = TransformationController();
  TapDownDetails _doubleTapDetails;

  ///dismiss thresholds for an image to be dimissed
  final Map<DismissDirection, double> _dismissThresholds = {
    DismissDirection.horizontal: 0.8,
    DismissDirection.vertical: 0.6
  };

  ///big circular progress indicator
  final Center _circularProgressIndicator = Center(
    child: SizedBox(
        width: 60,
        height: 60,
        child: CircularProgressIndicator(
          valueColor: new AlwaysStoppedAnimation<Color>(Colors.lightGreen[800]),
        )
    ),
  );

  void _handleDoubleTapDown(TapDownDetails details) {
    _doubleTapDetails = details;
  }

  void _handleDoubleTap() {
    if (_transformationController.value != Matrix4.identity()) {
      _transformationController.value = Matrix4.identity();
    } else {
      final position = _doubleTapDetails.localPosition;
      /// Fox a 2x zoom:
      _transformationController.value = Matrix4.identity()
      ..translate(-position.dx, -position.dy)
      ..scale(2.0);
    }
  }

@override
Widget build(BuildContext context) {
  return Center(
    child: Dismissible(
      key: const Key('key2'),
      dismissThresholds: _dismissThresholds,
      confirmDismiss: (direction) {
        return Future<bool>(() => _transformationController.value.isIdentity());
      },
      direction: DismissDirection.horizontal,
      onDismissed: (_) {print ('dismissed horiz.')},
      child: Dismissible(
        dismissThresholds: _dismissThresholds,
        key: const Key('key'),
        confirmDismiss: (direction) {
          return Future<bool>(() => _transformationController.value.isIdentity());
        },
        direction: DismissDirection.vertical,
        onDismissed: (_) {print ('dismissed vert.')},
        child: GestureDetector(
          onDoubleTapDown: _handleDoubleTapDown,
          onDoubleTap: _handleDoubleTap,
          child: InteractiveViewer(
            transformationController: _transformationController,
            minScale: 1.0,
            maxScale: 2.0,
            panEnabled: true,
            scaleEnabled: true,
            boundaryMargin: EdgeInsets.all(100.0),
            child: CachedNetworkImage(
              imageUrl: 'https://cdn.onlinewebfonts.com/svg/img_258083.png',
              placeholder: (context, url) => _circularProgressIndicator,
              fit: BoxFit.fitWidth,
              alignment: FractionalOffset.center,
            )
          ),
        ),
      ),
    )
  );
}

我通过设置 boundaryMargin:EdgeInsets.all(0.0),InteractiveViewer