如果两个容器在堆栈中完全相互重叠,那么当单击顶部的小部件时如何检测底部的onTap()
事件?
用例:
我的顶部容器是透明的。我正在使用此透明容器轻拍来为顶部小部件设置动画(此顶部小部件粘贴在场景的底部)。在点击时,我想在位置上为同一底部元素设置动画。
另外,我实现了自定义Rawgesture,但是我看不到手势竞技场冲突。仅在将元素定位为一个是父级而第二个是子级的情况下,才能检测到此竞技场冲突。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(children: <Widget>[
GestureDetector(
onTap: () {
print('green clicked.');
},
child: Container(
color: Colors.green,
width: 400,
height: 400,
),
),
GestureDetector(
onTap: () {
print('red clicked.');
},
child: Container(
color: Colors.red,
width: 200,
height: 200,
),
),
]),
);
}
}
在上述示例中,当我单击红色容器时,它将打印red clicked
,但是绿色容器中也有一部分。我想知道是否可以调用这两个事件?
谢谢。
答案 0 :(得分:3)
AFAIK,没有直接方法可以知道用户是否在其中轻拍了基础小部件。但是,我运行了您的红色和绿色容器代码,并通过onTapDown
事件
最简单的解决方案(不带onTapDown)::
添加了以下功能:
void onGreenClick()
{
print("Green clicked");
}
将Green的onTap处理程序更改为:
onTap: onGreenClick,
并在Red的onTap中将onGreenClick()添加为:
onTap: () {
print('red clicked.');
onGreenClick();
},
但是,正如您所猜测的,这仅在小部件彼此完全重叠时才有效。万一有红色容器存在但没有绿色的区域,则上面的区域将失效。为此,您可以使用onTapDown
,如下所示:
将onTapDown处理程序添加到红色和绿色(在GestureDetector下)为:
onTapDown: (TapDownDetails details) => onTapDown(context, details),
处理程序函数为:
void onTapDown(BuildContext context, TapDownDetails details) {
print('${details.globalPosition}');
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(details.globalPosition);
setState(() {
posx = localOffset.dx;
posy = localOffset.dy;
});
if (posx < 100.0 && posy < 100.0) onGreenClick();
}
现在,如果您看到最后一行,我们仅在特定的x,y坐标上调用onGreenClick。
因此,最终结果是即使在单击红色时,您也会在调试输出窗口中获得“绿色单击”。
完整的代码可用here