Flutter GectureDetector onTap 仅适用于文本子项

Vic*_*tor 2 gesturedetector flutter flutter-layout

我尝试创建一个应用程序,当用户点击屏幕上的任何地方时,该应用程序将背景颜色更改为随机颜色,但 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)),
            ),
          ),
        ));
  }
}
Run Code Online (Sandbox Code Playgroud)

Cra*_*Cat 5

设置behavior: HitTestBehavior.translucentGestureDetector.

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)),
  ),
),
Run Code Online (Sandbox Code Playgroud)


Pha*_*vij 1

实现此目的的另一种方法是使用带有行为属性的Stack顶级页面。ListenerHittestBehavior.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);
        });
      },
    ),
  ],
),
Run Code Online (Sandbox Code Playgroud)

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

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

但如果你使用 aGestureDetector代替Listenerfor 例如。如果您最终使用 aStack或将 aGestureDetector作为 a 中的子级GestureDetector,并具有相同的回调(如onTapandonTaponLongPressonLongPress),那么只有一个GestureDetectors 会触发。

因为GestureDetector他们会参加手势竞技场,比拼手势,最后只有一个人获胜。

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

缺点是 aListener可以接收原始指针事件,而 aGestureDetector则更复杂。

可以在这里找到更详细的解释