1

I want to make swipable image viewer and have InteractiveViewer inside PageView.builder.

class PageViewImageSwiper extends StatelessWidget {
final List<Image> images;
const PageViewImageSwiper({required this.images, super.key});
    
@override
Widget build(BuildContext context) {
// Need logic to make it true when two or more fingers on the screen
bool _swipeDisabled = false;

return Scaffold(
    body: Column(
      children: [
        Expanded(
          child: PageView.builder(
            physics: _swipeDisabled ? NeverScrollableScrollPhysics() : null,
            itemBuilder: (context, count) => InteractiveViewer(
              child: images[count],
            ),
          ),
        )
      ],
    ));
  }
}

But they conflicting and i want to disable PageView scroll when have two fingers on the screen.

LoToSS
  • 11
  • 2

2 Answers2

1

Here is a sample code on how to detect two fingers on the screen:

class PageViewImageSwiper extends StatefulWidget {
  final List<Image> images;
  const PageViewImageSwiper({Key? key, required this.images}) : super(key: key);

  @override
  State<PageViewImageSwiper> createState() => _PageViewImageSwiperState();
}

class _PageViewImageSwiperState extends State<PageViewImageSwiper> {
  @override
  Widget build(BuildContext context) {
    bool _swipeDisabled = false;
    int _pointers = 0;

    void _handleScaleUpdate(ScaleUpdateDetails details) {
      _pointers = details.pointerCount;
      if (_pointers >= 2) {
        _swipeDisabled = true;
      } else {
        _swipeDisabled = false;
      }
      setState(() {});
    }

    return GestureDetector(
      onScaleUpdate: _handleScaleUpdate,
      child: Scaffold(
          body: Column(
        children: [
          Expanded(
            child: PageView.builder(
              itemCount: widget.images.length,
              physics: _swipeDisabled ? NeverScrollableScrollPhysics() : null,
              itemBuilder: (context, count) => InteractiveViewer(
                child: widget.images[count],
              ),
            ),
          )
        ],
      )),
    );
  }
}

The main juice is the _handleScaleUpdate, as you can tell how many pointer events are on the screen from the pointer count of the scale update details.

Codefarmer
  • 684
  • 4
  • 8
0

Solved problem by adding Listener

class PageViewImageSwiper extends StatefulWidget {
  final List<Image> images;
  const PageViewImageSwiper({required this.images, super.key});

  @override
  State<PageViewImageSwiper> createState() => _PageViewImageSwiperState();
}

class _PageViewImageSwiperState extends State<PageViewImageSwiper> {
  @override
  Widget build(BuildContext context) {
// Need logic to make it true when two or more fingers on the screen
    Set<int> touchPositions = {};
    void savePointerPosition(int index) {
      setState(() {
        touchPositions.add(index);
      });
    }

    void clearPointerPosition(int index) {
      setState(() {
        touchPositions.remove(index);
      });
    }

    return Listener(
      onPointerDown: (opm) {
        savePointerPosition(opm.pointer);
      },
      onPointerMove: (opm) {
        savePointerPosition(opm.pointer);
      },
      onPointerCancel: (opc) {
        clearPointerPosition(opc.pointer);
      },
      onPointerUp: (opc) {
        clearPointerPosition(opc.pointer);
      },
      child: Scaffold(
          body: Column(
        children: [
          Expanded(
            child: PageView.builder(
              physics: touchPositions.length > 1
                  ? const NeverScrollableScrollPhysics()
                  : null,
              itemBuilder: (context, count) => InteractiveViewer(
                child: widget.images[count],
              ),
            ),
          )
        ],
      )),
    );
  }
}
LoToSS
  • 11
  • 2