I'm trying to simulate a tap event in flutter using hitTest as described in this post: How can I simulate a tap event on a Flutter widget?
Even though the hitTest returns true, the onTap event of the GestureDetector is not triggered
heres my code:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class TestHitTest extends StatefulWidget {
const TestHitTest({Key? key}) : super(key: key);
@override
State<TestHitTest> createState() => _TestHitTestState();
}
class _TestHitTestState extends State<TestHitTest> {
bool _testSuccessfull = false;
final GlobalKey _globalKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
key: _globalKey,
onTap: (){
setState(() {
_testSuccessfull = true;
});
},
child: Container(
width: 200,
height: 100,
color: _testSuccessfull? Colors.green:Colors.red,
),
),
SizedBox(height: 100,),
GestureDetector(
onTap: () {
final RenderObject? renderObject = _globalKey.currentContext?.findRenderObject();
final RenderBox? renderBox = renderObject is RenderBox? renderObject:null;
final hitTestResult = BoxHitTestResult();
print(renderBox?.hitTest(hitTestResult, position: Offset(renderBox.size.width/2,renderBox.size.height/2)));
},
child: Container(
width: 200,
height: 100,
color: Colors.blue,
child: Text(
'Perform hittest',
),
),
),
],
),
),
);
}
}
Since my final use case involves triggering onTap methods of widgets that might be covered by other widgets, I can't just use GestureBinding. The problem also occurs when obtaining the context directly instead of via the global key.
Note: I don't want to call the onTap method directly
output of flutter doctor -v:
[✓] Flutter (Channel stable, 2.10.4, on macOS 12.3.1 21E258 darwin-x64, locale de-DE)
• Flutter version 2.10.4 at /Users/test/Developer/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision c860cba910 (2 weeks ago), 2022-03-25 00:23:12 -0500
• Engine revision 57d3bac3dd
• Dart version 2.16.2
• DevTools version 2.9.2
[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
• Android SDK at /Users/test/Library/Android/sdk
• Platform android-32, build-tools 32.1.0-rc1
• Java binary at: /Applications/Development/Android Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 13.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.11.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2021.1)
• Android Studio at /Applications/Development/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)
[✓] IntelliJ IDEA Ultimate Edition (version 2020.3.3)
• IntelliJ at /Applications/Development/IntelliJ IDEA.app
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
[✓] VS Code (version 1.66.1)
• VS Code at /Applications/Development/Visual Studio Code.app/Contents
• Flutter extension version 3.38.1
[✓] Connected device (3 available)
• iPhone 13 (mobile) • 8EB86ECB-B851-40C7-B70B-3E93A91646B6 • ios • com.apple.CoreSimulator.SimRuntime.iOS-15-4 (simulator)
• macOS (desktop) • macos • darwin-x64 • macOS 12.3.1 21E258 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 100.0.4896.75
[✓] HTTP Host Availability
• All required HTTP hosts are available
• No issues found!
Finally figured it out: it is possible to use GestureBindings.handleEvent() instead of GestureBindings.handlePointerEvent(). That way, the specific HitTestResult can be passed and no Widgets that are before that widget can absorb the event.
Example:
//get render Box and perform hitTest
final RenderObject? renderObject = _globalKey.currentContext?.findRenderObject();
final RenderBox? renderBox = renderObject is RenderBox? renderObject:null;
final hitTestResult = BoxHitTestResult();
renderBox?.hitTest(hitTestResult, position: Offset(renderBox.size.width/2,renderBox.size.height/2));
//get BoxHitTestEntry
BoxHitTestEntry entry = hitTestResult.path.firstWhere((element) => element is BoxHitTestEntry) as BoxHitTestEntry;
//create Events and get GestureBinding Instance
GestureBinding instance = GestureBinding.instance!;
var event1 = PointerDownEvent(position: renderBox!.localToGlobal(Offset(renderBox.size.width/2,renderBox.size.height/2)));
var event2 = PointerUpEvent(position: renderBox.localToGlobal(Offset(renderBox.size.width/2,renderBox.size.height/2)));
//dispatch and handle events using GestureBinding
instance.dispatchEvent(event1, hitTestResult);
instance.dispatchEvent(event2, hitTestResult);
instance.handleEvent(event1, entry);
instance.handleEvent(event2, entry);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.