[英]Flutter HitTest not Triggering a Tap Event
我正在嘗試使用 hitTest 在 flutter 中模擬點擊事件,如本文所述: How can I simulate a tap event on a Flutter widget?
即使 hitTest 返回 true,也不會觸發 GestureDetector 的 onTap 事件
這是我的代碼:
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',
),
),
),
],
),
),
);
}
}
由於我的最終用例涉及觸發可能被其他小部件覆蓋的小部件的 onTap 方法,因此我不能只使用 GestureBinding。 當直接獲取上下文而不是通過全局鍵獲取上下文時,也會出現此問題。
注意:我不想直接調用onTap方法
output 的 flutter 醫生 -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!
終於想通了:可以使用 GestureBindings.handleEvent() 而不是 GestureBindings.handlePointerEvent()。 這樣,可以傳遞特定的 HitTestResult,並且該小部件之前的任何小部件都無法吸收該事件。
例子:
//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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.