Flutter - 在充满其他小部件的屏幕上检测点击

Posted

技术标签:

【中文标题】Flutter - 在充满其他小部件的屏幕上检测点击【英文标题】:Flutter - Detect Tap on the Screen that is filled with other Widgets 【发布时间】:2020-05-26 12:32:15 【问题描述】:

我正在尝试检测屏幕上的点击。我已经尝试了多种使用 GestureDetector 的变体,但这只会导致应用检测到点击子元素而不是屏幕

代码如下:

class QQHome extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Colors.blueGrey,
      ),
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text('QuoteQuota'),
        ),
        body: GestureDetector(
          onTap: () => print('Tapped'),
          child: QQBody(),
        ),
      ),
    );
  


class QQBody extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Center(
      child: Text(
        'Hello, World!'
      ),
    );
  

输出:当我点击“Hello, World!”时打印“tapped”。

预期的输出:当我点击屏幕上的任意位置且文本居中时打印“轻按”。

我该怎么做?

【问题讨论】:

【参考方案1】:

就像 Darshan 所说,您可以通过将身体包裹在这样的手势检测器中来触发 Tap...

body: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: () => print('Tapped'),
          child: QQBody(),
        ),

此外,在某些情况下,您可能需要避免在点击正文中的任意位置时触发点击其他小部件。这可以通过使用IgnorePointer Widget 来解决

body: GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () 
        print('This will click');
      ,

      // -------- No Widget below tree will be trigger click.

      child: IgnorePointer(
        ignoring: ClassLibrary.selected != null ? true : false,
        child: TabBarView(
          children: [
                   ...

【讨论】:

【参考方案2】:

您可以使用Stack:将图层相互叠加。 Stack 的好处是您可以根据需要安排堆栈顺序。 如果您想在触摸屏幕时执行某项操作,并在触摸屏幕上的按钮时执行其他操作,您可以通过将按钮放在GestureDetector 顶部轻松地使用堆栈来执行此操作。

以下是您的示例:

class QQHome extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Colors.blueGrey,
      ),
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text('QuoteQuota'),
        ),
        body: Stack(
          // Bottom to Top order
          children: <Widget> [
            QQBody(),
            GestureDetector(
              onTap: () => print('Tapped'),
            ),
          ]
        ),
      ),
    );
  


class QQBody extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Center(
      child: Text(
        'Hello, World!'
      ),
    );
  

【讨论】:

【参考方案3】:

使用GestureDetector's behavior 属性并将HitTestBehavior.opaque 传递给它,它会识别整个屏幕并在您点击屏幕上的任意位置时检测到点击。

body: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: () => print('Tapped'),
          child: QQBody(),
        ),

希望这能回答你的问题。

【讨论】:

嗨@Darshan,我有类似的要求。我希望当我点击屏幕上的任意位置而不是在控制台中打印“点击”时显示 QQBody。我是 Flutter 的新手,不知道如何实现这一点。我确实尝试用 QQBody 替换 print,但它没有用。您能否建议需要做什么。提前致谢!【参考方案4】:

请使用下面的代码--

class QQHome extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Colors.blueGrey,
      ),
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text('QuoteQuota'),
        ),
        body: GestureDetector(
          onTap: () => print('Tapped'),

          child: Container(
          height : MediaQuery.of(context).size.height,
          width : MediaQuery.of(context).size.width,
),
        ),
      ),
    );
  

【讨论】:

以上是关于Flutter - 在充满其他小部件的屏幕上检测点击的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Flutter 小部件适应不同的屏幕尺寸

Flutter:在屏幕上拖动小部件(不是拖放)

Flutter 小部件显示在所有屏幕上

如何在 Flutter 的同一屏幕上沿 ListView 显示小部件?

由于当前屏幕上的更新,防止 Flutter Provider 在前一屏幕中重建小部件

Flutter:如何将文本小部件中心放在屏幕上