Flutter GectureDetector onTap 仅适用于文本子项

Flutter GectureDetector onTap works only on text child

我尝试创建一个应用程序,当用户点击屏幕上的任意位置时,它会将背景颜色更改为随机颜色,但只有当我点击文本时,OnTap 功能才有效。请帮我解决一下。

这是我的代码:

import 'package:flutter/material.dart';
import 'dart:math';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MainVidget();
  }
}

class MainVidget extends StatefulWidget {
  @override
  MainVidgetState createState() => MainVidgetState();
}

class MainVidgetState extends State<MainVidget> {
  Color mainColor = Colors.white;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Welcome to Flutter',
        home: Scaffold(
          backgroundColor: mainColor,
          appBar: AppBar(
            title: Text('Tap anywhere'),
          ),
          body: GestureDetector(
            onTap: () {
              setState(() {
                mainColor = Color.fromRGBO(Random().nextInt(254) + 1,
                    Random().nextInt(254) + 1, Random().nextInt(254) + 1, 1);
              });
            },
            child: Center(
              child: Text('Hey there', style: TextStyle(fontSize: 32.0)),
            ),
          ),
        ));
  }
}

GestureDetector中设置behavior: HitTestBehavior.translucent

GestureDetector(
  behavior: HitTestBehavior.translucent, //or HitTestBehavior.opaque
  onTap: () {
    setState(() {
      mainColor = Color.fromRGBO(Random().nextInt(254) + 1,
          Random().nextInt(254) + 1, Random().nextInt(254) + 1, 1);
    });
  },
  child: Center(
    child: Text('Hey there', style: TextStyle(fontSize: 32.0)),
  ),
),

实现此目的的另一种方法是使用 Stack,顶级页面是 Listener,行为 属性 HittestBehavior.translucent.

body: Stack(
  children: <Widget>[
    Center(
      child: Text('Hey there', style: TextStyle(fontSize: 32.0)),
    ),
    Listener(
      behavior: HitTestBehavior.translucent,
      onPointerDown: (e) {
        setState(() {
          mainColor = Color.fromRGBO(Random().nextInt(254) + 1,
              Random().nextInt(254) + 1, Random().nextInt(254) + 1, 1);
        });
      },
    ),
  ],
),

现在说明为什么这种方法是一种稍微安全的方法:

  • 这不会妨碍具有相同回调的任何其他 GestureDetector

但是如果您使用 GestureDetector 而不是 Listener 例如。如果您最终使用 Stack 或将 GestureDetector 作为 GestureDetector 中的子项使用 onTaponTaponLongPress 等相同的回调和 onLongPress 等。然后只有 GestureDetector 之一会触发。

原因是 GestureDetectors 将参加手势竞技场并争夺手势,最后只有其中一个获胜。

但是 Listener 不会参与手势竞技场,因此无论如何它都会接收事件。

缺点是 Listener 可以接收原始指针事件,不像 GestureDetector 更复杂。

可以找到稍微详细一点的解释here