如何将 Taps 传递给顶部小部件下方的小部件? [英] How to pass Taps to widgets below the top widget?

查看:25
本文介绍了如何将 Taps 传递给顶部小部件下方的小部件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一个非常简单的

如果我用 IgnorePointer 类包围 ListView/SinglleChildScrollView,则整个滚动行为都会停止,并且对 ListView 的子项的任何点击也会停止停止不需要的工作.

如何在允许在 ListView 中滚动/点击的同时点击按钮(堆栈中的向后小部件)?或者我应该以不同的方式构建 Card Paginator 组件?

解决方案

可能重复 Flutter:如何使 ListView 对指针事件透明(但不是其非透明内容)?

您需要使用 GestureDetector 覆盖 onTapUp 将空容器包装在 ListView 中,以便您可以捕获屏幕上的点击位置:

GestureDetector(onTapUp: (TapUpDetails tapUpDetails) {print("onTapUp 全局:" + tapUpDetails.globalPosition.toString());},

然后,您需要使用该小部件的键来获取要点击的 ListView 后面的小部件的矩形:

RenderBox renderBox = _key.currentContext.findRenderObject();偏移 topLeftCorner = renderBox.localToGlobal(Offset.zero);大小 size = renderBox.size;矩形矩形 = topLeftCorner &尺寸;

最后你可以计算空容器上的点击是否在后面的小部件的矩形内,然后调用你的代码,就好像你在后面的小部件上有一个 GestureDetector:

//如果点击在背景小部件的边界内if (rectangle.contains(tapUpDetails.globalPosition)) {//你的代码在这里}

I'm trying to implement a very simple version of Card Paginator Component (single card) in Flutter.

Here is an example of a basic demo I've created:

class CardComponent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned(
          top: 20.0,
          left: 20.0,
          child: 
          GestureDetector(
          // onTap should run while the text is visible on the screen
          // The text will become invisible when the Listview gest scrolled upwards
          onTap: (){print('text tapped');},
            child:
          Container(
          alignment:Alignment.topCenter,
          color: Colors.blueAccent,
        // This is fixed Text over which the card should scroll
        child: Text('Test Button')))),
        ListView(
          children: [
            //  This margin in first empty container pushes the whole card downward and makes the 'Test Button visible'
            Container(margin: EdgeInsets.only(top: 50.0)),
            // This is where the scrolling card actually starts
            Container(color: Colors.cyan[100], height: 120.0, width: 20.0),
            Container(color: Colors.cyan, height: 120.0, width: 20.0),
            Container(color: Colors.cyan[100], height: 120.0, width: 20.0),
            Container(color: Colors.cyan, height: 120.0, width: 20.0),
            Container(color: Colors.cyan[100], height: 120.0, width: 20.0),
            Container(color: Colors.cyan, height: 120.0, width: 20.0),
          ]
        )
      ],
    );
  }
}

The issue I'm facing is, I'm unable to click the button when the card in not scrolled up. The fixed 'Test Button' is visible on the screen because of the empty dummy Container pushing the scrollable ListView downwards. Yet, since the ListView covers the full screen by default, hence the onTap never runs on tapping the button when it's visible.

If I surround the ListView/SinglleChildScrollView with IgnorePointer class, the whole scrolling behaviour stops and also any taps to the children of the ListView stops working which is not desired.

How to tap on the button (backward widget in Stack) while allowing scrolling/tapping in ListView? Or should I approach building Card Paginator Component is some different way?

解决方案

Potential duplicate of Flutter: How to make a ListView transparent to pointer events (but not its non-transparent contents)?

You need to wrap your empty Container within the ListView with a GestureDetector overriding onTapUp so that you can capture the tap position on the screen:

GestureDetector(
  onTapUp: (TapUpDetails tapUpDetails) {
    print("onTapUp global: " + tapUpDetails.globalPosition.toString());
  },

You then need to get the rectangle of the widget behind the ListView that you want to tap on, by using that widget's key:

RenderBox renderBox = _key.currentContext.findRenderObject();
Offset topLeftCorner = renderBox.localToGlobal(Offset.zero);
Size size = renderBox.size;
Rect rectangle = topLeftCorner & size;

And finally you can calculate whether the tap on the empty Container is within the rectangle of the widget behind, and at that point invoke your code as if you had a GestureDetector on the widget behind:

// if tap is within boundaries of the background widget
if (rectangle.contains(tapUpDetails.globalPosition)) {
  // your code here
}

这篇关于如何将 Taps 传递给顶部小部件下方的小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆