Skip to content

Instantly share code, notes, and snippets.

@Nash0x7E2
Last active November 3, 2023 08:56
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save Nash0x7E2/08acca529096d93f3df0f60f9c034056 to your computer and use it in GitHub Desktop.
Save Nash0x7E2/08acca529096d93f3df0f60f9c034056 to your computer and use it in GitHub Desktop.
[DEPRECATED] Sample code on how to enable gesture pass through so that both the parent and the child widget receive the gesture.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
//Main function. The entry point for your Flutter app.
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: DemoApp(),
),
),
);
}
// Simple demo app which consists of two containers. The goal is to allow multiple gestures into the arena.
// Everything is handled manually with the use of `RawGestureDetector` and a custom `GestureRecognizer`(It extends `TapGestureRecognizer`).
// The custom GestureRecognizer, `AllowMultipleGestureRecognizer` is added to the gesture list and creates a `GestureRecognizerFactoryWithHandlers` of type `AllowMultipleGestureRecognizer`.
// It creates a gesture recognizer factory with the given callbacks, in this case, an `onTap`.
// It listens for an instance of `onTap` then prints text to the console when it is called. Note that the `RawGestureDetector` code is the same for both
// containers. The only difference being the text that is printed(Used as a way to identify the widget)
class DemoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return RawGestureDetector(
gestures: {
AllowMultipleGestureRecognizer: GestureRecognizerFactoryWithHandlers<
AllowMultipleGestureRecognizer>(
() => AllowMultipleGestureRecognizer(),
(AllowMultipleGestureRecognizer instance) {
instance.onTap = () => print('Episode 4 is best! (parent container) ');
},
)
},
behavior: HitTestBehavior.opaque,
//Parent Container
child: Container(
color: Colors.blueAccent,
child: Center(
//Wraps the second container in RawGestureDetector
child: RawGestureDetector(
gestures: {
AllowMultipleGestureRecognizer:
GestureRecognizerFactoryWithHandlers<
AllowMultipleGestureRecognizer>(
() => AllowMultipleGestureRecognizer(), //constructor
(AllowMultipleGestureRecognizer instance) { //initializer
instance.onTap = () => print('Episode 8 is best! (nested container)');
},
)
},
//Creates the nested container within the first.
child: Container(
color: Colors.yellowAccent,
width: 300.0,
height: 400.0,
),
),
),
),
);
}
}
// Custom Gesture Recognizer.
// rejectGesture() is overridden. When a gesture is rejected, this is the function that is called. By default, it disposes of the
// Recognizer and runs clean up. However we modified it so that instead the Recognizer is disposed of, it is actually manually added.
// The result is instead you have one Recognizer winning the Arena, you have two. It is a win-win.
class AllowMultipleGestureRecognizer extends TapGestureRecognizer {
@override
void rejectGesture(int pointer) {
acceptGesture(pointer);
}
}
@guitoof
Copy link

guitoof commented Mar 18, 2022

Great, let me know how it goes 😉

@TheManuz
Copy link

TheManuz commented Mar 18, 2022

I've added hitTestBehavior: HitTestBehaviour.transluscent to the XGestureDetector Listener, and finally both events are firing.

Sadly, I've got a problem with the order of firing: apparently, the child fires always before the parent.

My current configuration is to have the parent widget as the one responsible for logging the UI events, and the child is the original button, unchanged.

Since the actual original button triggers a navigation event (also logged), the result is something like this:

  1. child: execute navigation
  2. navigation log event fires
  3. parent: onTap log event fires

so I'm logging that the navigation happened before the click, and this is obviously wrong.

Yay, it works! The order is correct, all these tries confused me!
Now I'm up for some cleaning and it'll be done!

Thank you very much for your help @guitoof

@2p31-1
Copy link

2p31-1 commented Nov 3, 2023

Are there any alternative codes for this?

@guitoof
Copy link

guitoof commented Nov 3, 2023

Hi @2p31-1 ,
To achieve what I wanted, I drilled down to use Flutter's lower level: Listener widget. As @TheManuz said, in this case it fires pretty well.
After struggling with this, I decided to make a talk about it to explain what I've understood from the subject. If you want to take a look, maybe that'll clarify some things for you:
https://www.droidcon.com/2023/08/06/understanding-flutters-handling-of-gestures/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment