PhotoView package not working correctly inside a Stack widget

28 views Asked by At

When using the PhotoView package and using a stack to overlap more images the zoom and scroll function is not working in the overlapping area.

I am using the PhotoView Dart package to show a zoomable and scrollable image. I need to overlap an additional image created with the Paint function. I used the Stack() widget to overlap the images and it works. Problem is that in the zone where there is the overlap the image managed with PhotoView is not reacting to zoom and scroll actions. However the image works properly out of the overlapping zone. How can I solve it making the image reacting correctly in any zone?

Here is the code I used:

class imageViewerState extends State<imageViewer> {
  bool showCaliper = false;

  @override
  Widget build(BuildContext context) {
    Orientation orientation = MediaQuery.of(context).orientation;

    return MediaQuery(
        data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
        child: Container(
            child: Stack(alignment: Alignment.center, children: [
          /*Container(
                color: ui.cardcolor,
              ),*/

          PhotoView(
            initialScale: orientation == Orientation.portrait
                ? PhotoViewComputedScale.covered * 0.5
                : PhotoViewComputedScale.covered * 0.9,
            basePosition: Alignment.centerLeft,
            //minScale: PhotoViewComputedScale.contained,
            //maxScale: PhotoViewComputedScale.covered * 4.1,
            backgroundDecoration: BoxDecoration(
                image: DecorationImage(
              colorFilter: const ColorFilter.mode(
                Colors.white,
                BlendMode.softLight,
              ),
              image: globals
                  .backgroundImage, //AssetImage("images/app_images/Blur.png"),
              fit: BoxFit.cover,
            )),
            imageProvider: AssetImage(
              widget.imagepath,
            ),
          ),
          /*Column(
                children: [
                  SizedBox(height: 60,),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(Icons.content_paste, size: 25,color: Colors.black54),
                      Text('  ' +widget.titolo, style: ui.cardtitle),

                    ],
                  ),
                ],
              ),

               */
          SafeArea(
            child: Padding(
              padding: const EdgeInsets.all(15.0),
              child: Column(
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      GestureDetector(
                          onTap: () {
                            setState(() {
                              showCaliper = !showCaliper;
                            });
                          },
                          child: Visibility(
                              visible: false,
                              child: Icon(
                                CupertinoIcons.arrow_left_right_square,
                                color: Colors.black54,
                              ))),
                      GestureDetector(
                          onTap: () {
                            Navigator.pop(context);
                            ;
                          },
                          child: Icon(
                            CupertinoIcons.clear_circled_solid,
                            color: Colors.black54,
                          )),
                    ],
                  ),
                ],
              ),
            ),
          ),
          Visibility(
            visible: showCaliper,
            child: CustomPaint(
              //                       <-- CustomPaint widget
              size: Size(300, 300),
              painter: MyPainter(),
            ),
          ),
        ])
            //widget.image,
            ));
  }
}

class MyPainter extends CustomPainter {
  //         <-- CustomPainter class
  @override
  void paint(Canvas canvas, Size size) {
    final p1 = Offset(50, 50);
    final p2 = Offset(50, 250);
    final paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 4;
    canvas.drawLine(p1, p2, paint);
  }

  @override
  bool shouldRepaint(CustomPainter old) {
    return true;
  }
1

There are 1 answers

2
Mäddin On

If the other widgets in the stack do not require gestures, you can wrap them in an IgnorePointer. This way, they will not block the gestures intended for PhotoView.

  @override
  Widget build(BuildContext context) {
    Orientation orientation = MediaQuery.of(context).orientation;

    return MediaQuery(
      data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
      child: Container(
         child: Stack(alignment: Alignment.center, children: [
      PhotoView(...),
      IgnorePointer(child: SafeArea(
        child: ...
      ),),
      IgnorePointer(child: Visibility(
        visible: showCaliper,
        child: CustomPaint(
          size: Size(300, 300),
          painter: MyPainter(),
        ),
      ),),
    ])
  ));
}