Chris
Chris

Reputation: 2274

Flutter pass Gesture Detection Details to lower Stack widgets

I have a Stack with two widgets on it. The lower one should be able to detect GestureDetection but that is not possible because the one above is blocking it. My setup:

    return Stack(
  children: [
    Hero(
      tag: month.name + 'image',
      child: Container(
        height: _scaledWidth,
        width: _scaledWidth,
        child: PaintService.getCollageImagesFromCollageOption(
          month.collageOption,
          month.images,
          _scaledWidth,
        ),
      ),
    ),
    Hero(
      tag: month.name + 'shape',
      child: Container(
        height: _scaledWidth,
        width: _scaledWidth,
        child: PaintService.getShapeFromCollageOption(
            month.collageOption, _scaledWidth),
      ),
    ),
  ],
);

enter image description here

The upper widget is the white frame in the picture, which has to be on top of the images. But the images should be transformable which I do like this:

  Widget build(BuildContext context) {
final _zoom = useState<double>(1.0);
final _previousZoom = useState<double>(1.0);
final _offset = useState<Offset>(Offset.zero);
final _previousOffset = useState<Offset>(Offset.zero);
final _startingFocalPoint = useState<Offset>(Offset.zero);

final _zoom_2 = useState<double>(1.0);
final _previousZoom_2 = useState<double>(1.0);
final _offset_2 = useState<Offset>(Offset.zero);
final _previousOffset_2 = useState<Offset>(Offset.zero);
final _startingFocalPoint_2 = useState<Offset>(Offset.zero);
return Stack(
  children: [
    Positioned(
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      child: GestureDetector(
        onTap: () => print("tapped"),
        onScaleStart: (details) {
          _startingFocalPoint.value = details.focalPoint;
          _previousOffset.value = _offset.value;
          _previousZoom.value = _zoom.value;
        },
        onScaleUpdate: (details) {
          _zoom.value = _previousZoom.value * details.scale;
          final Offset normalizedOffset =
              (_startingFocalPoint.value - _previousOffset.value) /
                  _previousZoom.value;
          _offset.value =
              details.focalPoint - normalizedOffset * _zoom.value;
        },
        child: ClipPath(
          clipper: _Position1ClipperImage(),
          child: Transform(
            transform: Matrix4.identity()
              ..translate(_offset.value.dx, _offset.value.dy)
              ..scale(_zoom.value),
            child: Image.asset(widget.images[0].path,
                width: widget.width,
                height: widget.width,
                fit: BoxFit.fill),
          ),
        ),
      ),
    ),
    Positioned(
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      child: GestureDetector(
        onTap: () => print("tapped"),
        onScaleStart: (details) {
          _startingFocalPoint_2.value = details.focalPoint;
          _previousOffset_2.value = _offset_2.value;
          _previousZoom_2.value = _zoom_2.value;
        },
        onScaleUpdate: (details) {
          _zoom_2.value = _previousZoom_2.value * details.scale;
          final Offset normalizedOffset =
              (_startingFocalPoint_2.value - _previousOffset_2.value) /
                  _previousZoom_2.value;
          _offset_2.value =
              details.focalPoint - normalizedOffset * _zoom_2.value;
        },
        child: ClipPath(
          clipper: _Position2ClipperImage(),
          child: Transform(
            transform: Matrix4.identity()
              ..translate(_offset_2.value.dx, _offset_2.value.dy)
              ..scale(_zoom_2.value),
            child: Image.asset(widget.images[1].path,
                width: widget.width,
                height: widget.width,
                fit: BoxFit.fill),
          ),
        ),
      ),
    ),
  ],
);


}

Like I said this is not working if I have the second widget on top of the images (first code snippet).

I know I could simply move the GestureDetector to the top-level widgets. But how can I pass that info to my images then? I am quite stuck here...

Let me know if you need more info!

Upvotes: 1

Views: 1351

Answers (1)

Jigar Patel
Jigar Patel

Reputation: 5423

Try wrapping the top widget with an IgnorePointer widget.

  IgnorePointer(
    child: Hero(
      tag: month.name + 'shape',
      child: Container(
        height: _scaledWidth,
        width: _scaledWidth,
        child: PaintService.getShapeFromCollageOption(
            month.collageOption, _scaledWidth),
      ),
    ),
  )

Upvotes: 4

Related Questions