anonymous-dev
anonymous-dev

Reputation: 3539

Wrapping InteractiveViewer in GestureDetector causes InteractiveViewer input to respond poorly

I have a gesture detector and wrapped it around a interactive viewer. But when I do, panning and scaling no longer work on my InteractiveViewer. Or atleast it responds very poorly to input.

This is my GestureDetector

class MyPage extends StatelessWidget {
  const MyPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (_) => context.read<TutorialBloc>().rewind(),
      onVerticalDragStart: (_) => context.read<TutorialBloc>().rewind(),
      onHorizontalDragStart: (_) => context.read<TutorialBloc>().rewind(),
      onTapUp: (_) => context.read<TutorialBloc>().resume(),
      onVerticalDragEnd: (_) => context.read<TutorialBloc>().resume(),
      onHorizontalDragEnd: (_) => context.read<TutorialBloc>().resume(),
      child: Scaffold(
        body: Center(
          child: Container(
            width: 100,
            height: 100,
            child: InteractiveViewer(
              child: Container(color: Colors.blue),
            ),
          ),
        ),
      ),
    );
  }
}

The InteractiveViewer will respond poorly to input. I tried setting this

behavior: HitTestBehavior.deferToChild

and

behavior: HitTestBehavior.translucent

But it does not work

How can I fix this?

Also with the gesture detector I am trying to detect a tap anywhere on the page whil the interactive viewer only is a small part of the page.

Side Note: Just is just some example code the to illustrate the widget structure. In reality the container is not just blue and the Interactive Viewer is nested deeper.

Upvotes: 2

Views: 1693

Answers (2)

Amir Panahandeh
Amir Panahandeh

Reputation: 9059

You can use a Listener if you just want to get notified when user starts and stops touching things under it. With GestureDetector there is no way you can catch gestures and also send it to InteractiveViewer being it's child. Here is an example:

Listener(
  onPointerDown: (_) {
    // rewind
  },
  onPointerCancel: (_) {
    // resume
  },
  onPointerUp: (_) {
    // resume
  },
  child: Scaffold(
    body: Center(
      child: Container(
        width: 100,
        height: 100,
        child: InteractiveViewer(
          child: Container(color: Colors.blue),
        ),
      ),
    ),
  ),
),

Upvotes: 2

Hemanth S
Hemanth S

Reputation: 688

check this you might not able to see the container moving or scaling but when you put something bigger than screen sizes like an image or something InteractiveViewer will kick into work below example could help but the exact problem you want to fix might help with basics. Replace container with SizedBox to work properly

    import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';

    void main() async {
      runApp(MyApp());
    }

    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);

      @override
      _MyAppState createState() => _MyAppState();
    }

    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(),
          darkTheme: ThemeData.dark(),
          home: Provider(
            create: (context) => TutorialBloc(),
            child: MyPage(),
          ),
        );
      }
    }

    class MyPage extends StatelessWidget {
      const MyPage({Key? key}) : super(key: key);

      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTapDown: (_) => context.read<TutorialBloc>().rewind(),
          onVerticalDragStart: (_) => context.read<TutorialBloc>().rewind(),
          onHorizontalDragStart: (_) => context.read<TutorialBloc>().rewind(),
          onTapUp: (_) => context.read<TutorialBloc>().resume(),
          onVerticalDragEnd: (_) => context.read<TutorialBloc>().resume(),
          onHorizontalDragEnd: (_) => context.read<TutorialBloc>().resume(),
          child: Scaffold(
            body: Center(
              child: SizedBox(
                width: 100,
                height: 100,
                child: InteractiveViewer(
                  child: Image.network(
                      'https://c4.wallpaperflare.com/wallpaper/500/442/354/outrun-vaporwave-hd-wallpaper-preview.jpg'),
                ),
              ),
            ),
          ),
        );
      }
    }

    class TutorialBloc {
      void rewind() {
        debugPrint('rewind');
      }

      void resume() {
        debugPrint('resume');
      }
    }

Upvotes: 0

Related Questions