3

1)如果我有这个,当我点击孩子Container时它不会打印“点击”:

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
    ),
  ),
),

2)如果我有这个,当我点击孩子时Container,它会打印“点击”:

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      decoration: BoxDecoration(),
    ),
  ),
),

3)如果我有这个,当我Container在文本之外点击 child 时,它会打印“tap”:

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      child: Text("A"),
    ),
  ),
),

有人可以解释一下这三种行为吗?

4

2 回答 2

8
  1. A Containerwith bounds(height and width)只不过是其他小部件进入其中的占位符。由于您没有child向它或任何其他属性(例如color或)提供任何decoration内容,因此 .container被认为是不可见的GestureDetector

根据官方GestureDetector文档,by default a GestureDetector with an invisible child ignores touches. this behavior can be controlled with behavior.

如果您仍然希望占位符container被识别为点击事件,请使用behavior的属性GestureDetector,这将告诉 GestureDetector 点击容器,然后您将看到tap打印,如下所示:

Container(
          color: Colors.red,
          child: GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTap: () => print('tap'),
            child: Container(
              width: 100,
              height: 100,
            ),
          ),
        ),
  1. 在这种情况下,由于您提供了decorationproperty 和 used BoxDecoration(),它会根据其父小部件提供的边界呈现一个框。所以,它container有一个盒子形状。为了查看盒子形状在容器内是如何呈现的,只需提供一个border属性,如下所示:
Container(
        color: Colors.red,
        child: GestureDetector(
          onTap: () => print('tap'),
          child: Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
              border: Border.all(color: Colors.yellow, width: 4)
            ),
          ),

在此处输入图像描述

您可以看到yellow跨越整个container尺寸的边框,它充当顶部的一层container,现在被认为是可点击的。因此,GestureDetector 的点击被识别并且您看到tap打印。

  1. 在这种情况下,由于您已将child小部件提供为textGestureDetector因此将其标识为小部件可见并因此tap被打印,无论您是点击文本还是外部,因为它GestureDetector本身没有大小,它依赖于孩子的大小,在这种情况下是bounds(高度和宽度)。因此,它认为整个有界区域都是可点击的,并且您可以在其中的tap任何位置打印事件。

希望这能回答你的问题。

于 2019-10-24T09:11:27.910 回答
0

首先要了解,GestureDetector仅检测对其 绘制的区域的点击child,而忽略其设置的行为。现在让我们来看看你的案例。


案例1:(未检测到触摸)

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container( // child Container (has nothing to draw on screen)
      width: 100,
      height: 100,
    ),
  ),
),

孩子Container没有在屏幕上画任何东西,所以GestureDetector不允许点击。但是您会说它同时具有widthheight,是的,您是对的,但它没有任何东西可以在屏幕上绘制。

如果你给它任何colordecoration,或任何child东西,它就会有东西要画,因此它能够检测到点击。


案例 2(检测到触摸):

Container( 
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container( // child Container
      width: 100,
      height: 100,
      decoration: BoxDecoration(), // has something to draw on screen
    ),
  ),
),

在这里,您正在给孩子Container一个装饰,以便它可以在屏幕上绘制一些东西,并GestureDetector允许点击。


案例 3(检测触摸):

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container( // child Container 
      width: 100,
      height: 100,
      child: Text("A"), // has something to draw on screen 
    ),
  ),
),

在这里,您正在给孩子Containera Text,因此可以在屏幕上绘制一些东西,从而启用点击。

注意:不仅Text孩子的整个区域Container都会收到点击,因为GestureDetector直接带有并设置为child,而不仅仅是.Containerwidthheight100Text

于 2019-10-24T17:59:39.340 回答