Gpack
Gpack

Reputation: 2193

How to detect scale and pan gesture in an AndroidView or UiKitView in Flutter?

I'm using flutter_pdfview to display a PDF in my Flutter App. Under the hood, the PDFView widget uses an AndroidView or a UiKitView depending on the platform.
I would like to get the coordinates of a tap event relatively to the PDF document knowing that a user can zoom and pan on the PDF.
For this, I would need to subscribe to scale and pan events in order to know which part of the document is currently displayed on the screen. Then I could figure out where exactly the user taps.

I've tried passing my own ScaleGestureRecognizer and PanGestureRecognizer. Unfortunately, the onUpdate(), onStart() never seem to be triggered.

Here's my code:

class PDFViewer extends StatelessWidget {
  PDFViewer({this.filePath});

  final String filePath;

  @override
  Widget build(BuildContext context) {
    final scale = ScaleGestureRecognizer()
      ..onUpdate = (details) {
        print(details.scale);
      };
    final pan = PanGestureRecognizer()
      ..onUpdate = (details) {
        print(details.delta);
      }
      ..onStart = (_) {
        print('Start pan');
      }
      ..onEnd = (_) {
        print('End pan');
      };

    return PDFView(
      filePath: filePath,
      gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
        Factory<ScaleGestureRecognizer>(() => scale),
        Factory<PanGestureRecognizer>(() => pan),
      },
    );
  }
}

Upvotes: 0

Views: 855

Answers (1)

Chrisbin Sunny
Chrisbin Sunny

Reputation: 61

I found a solution for the issue. I was checking for the presense of onTapDown and added

gestureRecognizers: Set()
        ..add(Factory<TapGestureRecognizer>(() => TapGestureRecognizer()
          ..onTapDown = (tap) {
            print("hell bro");
          })),

But, it didn't work somehow. I was checking for other solutions and thought to add GestureDetector and detect tap from that.

So, I just wrapped PDFView with a GestureDetector. Surprisingly, gestureRecognizers inside PDFView worked after adding GestureDetector() Widget. Since I was checking for onTapDown event with gestureRecognizers, I added onTap parameter in GestureDetector.

My Widget looked like this:

GestureDetector(
    onTap: (){}, //This has to be added. Won't work without this.
    child: PDFView(
      filePath: widget.link,
      onError: (error) {
        print(error.toString());
      },
      onPageError: (page, error) {
        print('$page: ${error.toString()}');
      },
      onViewCreated: (PDFViewController pdfViewController) {
        pdfController=pdfViewController;
      },
      onPageChanged: (a, b){
        visible=false;
      },
      gestureRecognizers: Set()
        ..add(Factory<TapGestureRecognizer>(() => TapGestureRecognizer()
          ..onTapDown = (tap) {
            print("Tap Down Gesture Detected");
          })),
    ),
  )

So, for your case I guess you'll have to add the following code:

return GestureDetector(
            onScaleStart: (a){}, //This has to be added. Won't work without this.
            onPanStart: (a){}, //This has to be added. Won't work without this.
            child: PDFView(
              filePath: filePath,
              gestureRecognizers: Set()
                ..add(
                    Factory<OneSequenceGestureRecognizer>(() => scale)
                )
                ..add(
                Factory<OneSequenceGestureRecognizer>(() => pan),
            ),)
          );

Upvotes: 1

Related Questions