如何将 Taps 传递给顶部小部件下方的小部件?

May*_*ate 6 listview flutter flutter-layout

我正在尝试在 Flutter 中实现一个非常简单的Card Paginator 组件(单卡)版本。

这是我创建的基本演示的示例:

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),
          ]
        )
      ],
    );
  }
}

Run Code Online (Sandbox Code Playgroud)

我面临的问题是,当卡片没有向上滚动时,我无法点击按钮。固定的“测试按钮”在屏幕上可见,因为空的虚拟容器ListView向下推动可滚动。然而,由于ListView默认情况下覆盖全屏,因此onTap当它可见时点击按钮永远不会运行。

在此处输入图片说明

如果我用类包围ListView/ ,则整个滚动行为都会停止,并且对 ListView 子项的任何点击也会停止工作,这是不希望的。SinglleChildScrollViewIgnorePointer

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

Ovi*_*diu 5

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

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

GestureDetector(
  onTapUp: (TapUpDetails tapUpDetails) {
    print("onTapUp global: " + tapUpDetails.globalPosition.toString());
  },
Run Code Online (Sandbox Code Playgroud)

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

RenderBox renderBox = _key.currentContext.findRenderObject();
Offset topLeftCorner = renderBox.localToGlobal(Offset.zero);
Size size = renderBox.size;
Rect rectangle = topLeftCorner & size;
Run Code Online (Sandbox Code Playgroud)

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

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


Aak*_*mar 2

我不知道您是否想要根据当前代码修复带有按钮的栏高度,但我可以根据您的共享卡片分页器组件帮助您进行设计。

为此,您可以使用CustomScrollViewwith SliverAppBar

这是代码

   CustomScrollView(
      slivers: <Widget>[
        SliverAppBar(
          backgroundColor: Colors.white,
          expandedHeight: 200,
          centerTitle: true,
          pinned: true,
          elevation: 0,
          flexibleSpace: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(
                child: Center(
                  child: Container(
                      padding: const EdgeInsets.all(10.0),
                      child: CircleAvatar(
                        backgroundColor: Colors.grey.shade400,
                        child: Image.asset("assets/user.png"),
                        maxRadius: 80,
                      )),
                ),
              ),
            ],
          ),
        ),
        SliverToBoxAdapter(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Center(child: Text("Aakash Kumar", style: Theme.of(context).textTheme.headline,)),
          ),
        ),
        SliverFixedExtentList(
          itemExtent: 150.0,
          delegate: SliverChildListDelegate(
            [
              Container(color: Colors.red),
              Container(color: Colors.purple),
              Container(color: Colors.green),
              Container(color: Colors.orange),
              Container(color: Colors.yellow),
              Container(color: Colors.pink),
            ],
          ),
        ),
      ],
    );
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助...