how to fix InteractiveViewer and scrollviews competing for gestures

Viewed 148

I have a vertical scrollView then a horizontal pageView containing images wrapped inside InteractiveViewer.

but it's quite a mess when I try zooming-in with the InteractiveViewer. all those scrollviews are competing for the gestures and I was wonding an easier way to get that fixed.

Edit: So the problem seem to be with onScale gesture(GestureDetector()) or 2 pointer gestures

I have something like

CustomScrollView(
  slivers: [
   const SliverToBoxAdapter(
         child: Container(
           width: double.infinity,
           height: 400,
           child: PageView(
             ...
             InteractiveViewer()
             ...
        )
      )
    ),
 ]
)
1 Answers

you can disable physic from relevant widget when user start to use interactive, maybe add some condition based on scale, finger, etc.

  ScrollPhysics _pagePhysics = const PageScrollPhysics();
  ScrollPhysics _customScrollViewPhysics = const ScrollPhysics();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CustomScrollView(
          // assign physic for scroll ------------------------
          physics: _customScrollViewPhysics,
          slivers: [
            SliverToBoxAdapter(
              child: SizedBox(
                height: 400,
                child: PageView(
                  // assign physic for page view --------------------
                  physics: _pagePhysics,
                  children: [
                    Container(
                      color: Colors.blue,
                    ),
                    InteractiveViewer(
                      onInteractionStart: (details) {
                        /// you can add some condition like this
                        //if use 2 finger
                        //if(details.pointerCount == 2){}

                        // then disable physic
                        setState(() {
                          _pagePhysics = const NeverScrollableScrollPhysics();
                          _customScrollViewPhysics =
                              const NeverScrollableScrollPhysics();
                        });
                        
                      },
                      onInteractionUpdate: (details) {
                        //condition based on scale
                        if (details.scale == 1.2) {}
                      },
                      onInteractionEnd: (details) {
                        // after interaction revert it
                        setState(() {
                          _pagePhysics = const PageScrollPhysics();
                          _customScrollViewPhysics = const ScrollPhysics();
                        });
                        
                      },
                      child: Container(
                        color: Colors.yellow,
                        child: const Text("Lorem Ipsum"),
                      ),
                    )
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }

and if interactiveviewer leave no space for pageview or customScroll its always nice to add some button so you user dont stuck on InteractiveViewer. you should make your ui like this :

enter image description here

Related