如何将扑扑中的ontap事件委托给堆栈中的底部小部件?

时间:2020-03-21 23:00:46

标签: flutter flutter-layout

如果两个容器在堆栈中完全相互重叠,那么当单击顶部的小部件时如何检测底部的onTap()事件?

用例:

我的顶部容器是透明的。我正在使用此透明容器轻拍来为顶部小部件设置动画(此顶部小部件粘贴在场景的底部)。在点击时,我想在位置上为同一底部元素设置动画。

enter image description here

另外,我实现了自定义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,但是绿色容器中也有一部分。我想知道是否可以调用这两个事件?

谢谢。

1 个答案:

答案 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