Flutter 颤振-轻敲/触摸区域如何工作?

Flutter 颤振-轻敲/触摸区域如何工作?,flutter,flutter-layout,flutter-widget,Flutter,Flutter Layout,Flutter Widget,1) 如果我有这个,当我点击子容器时,它不会打印“点击”: Container( color: Colors.red, child: GestureDetector( onTap: () => print('tap'), child: Container( width: 100, height: 100, ), ), ), 2) 如果我有这个,当我点击子容器时,它会打印“点击”: Container( color: Colo

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

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
    ),
  ),
),
2) 如果我有这个,当我点击子容器时,它会打印“点击”:

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      decoration: BoxDecoration(),
    ),
  ),
),
Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      child: Text("A"),
    ),
  ),
),
3) 如果我有这个,当我点击子容器时,在文本外,它会打印“点击”:

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      decoration: BoxDecoration(),
    ),
  ),
),
Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      child: Text("A"),
    ),
  ),
),
有人能给我解释一下这三种行为吗

  • 带有边界(高度和宽度)的
    容器
    只不过是其他小部件进入其中的占位符。由于您没有向其提供任何
    子对象
    或任何其他属性,如
    颜色
    装饰
    ,因此
    容器
    对于
    手势检测器
    是不可见的
  • 根据官方文件,
    默认情况下,带有不可见子对象的手势检测器会忽略触摸。此行为可以通过行为控制。

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

    Container(
              color: Colors.red,
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () => print('tap'),
                child: Container(
                  width: 100,
                  height: 100,
                ),
              ),
            ),
    
  • 在本例中,由于您提供了
    decoration
    属性并使用了
    BoxDecoration()
    ,因此它根据其父窗口小部件提供的边界呈现一个框。因此,
    容器
    具有长方体形状。 为了查看长方体形状在容器中的渲染方式,只需提供一个
    border
    属性,如下所示:
  • 您可以看到跨越整个
    容器
    大小的
    黄色
    边框,它作为
    容器
    顶部的一层,现在被认为是可点击的。 因此,GestureDetector的点击被识别,您可以看到
    tap
    打印

  • 在这种情况下,由于您提供了
    小部件作为
    文本
    手势检测器
    识别它,因为小部件是可见的,因此打印
    点击
    ,而不管您是点击文本还是点击文本外部,因为
    手势检测器
    本身没有大小,它取决于子对象的大小,在本例中是
    边界
    (高度和宽度)。因此,它认为整个有界区域是可点击的,并且您可以在其中的任何位置打印
    tap
    事件

  • 希望这能回答您的问题。

    首先要了解
    手势检测器
    只检测由其
    子对象
    绘制的区域上的点击,而忽略其设置的行为。现在让我们来看看你的案例。
    案例1:(未检测到触摸)

    容器
    没有在屏幕上绘制任何内容,因此
    手势检测器
    不允许单击。但你会说它有宽度和高度,是的,你是对的,但它没有任何东西可以在屏幕上画

    如果你给它任何
    颜色
    装饰
    ,或任何
    子对象
    ,它都会有东西要画,因此它能够检测到水龙头


    案例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(
      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 
        ),
      ),
    ),
    
    在这里,您给孩子
    容器
    一个装饰,这样它就可以在屏幕上绘制一些东西,而
    手势检测器
    将允许单击


    案例3(检测触摸):

    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(
      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 
        ),
      ),
    ),
    
    在这里,您将给孩子
    容器
    一个
    文本
    ,从而在屏幕上绘制一些东西,从而启用单击


    注意:不仅
    文本
    而且子
    容器的整个区域
    都会收到点击,因为
    手势检测器
    直接
    child
    容器
    ,宽度和高度设置为
    100
    ,而不仅仅是
    文本

    尝试以下行为示例:HitTestBehavior.半透明,手势检测感谢您指出这一点,但我仍然不明白为什么默认行为为1)不打印“点击”,2)打印,3)在文本外点击时打印。太棒了!我觉得有点让人困惑,在有界区域被认为是可点击的,而在这种情况下它不是,仅仅因为它有一个孩子。如果在3)中文本外的有界区域不可点击,则更明显,您可以使用1)中的行为属性使其可点击。我想是这样做的,因为手势检测器只知道它的直接子对象。谢谢,我仍然认为这个案例令人困惑,因为容器没有在文本之外画出任何东西,而且当案例中的部分不存在时,该部分是可点击的,如果使用
    color
    属性,您会看到
    容器实际上是在屏幕上绘制的。要验证您是否可以在
    列中使用此子
    容器
    ,并在其下方放置一些内容,您会看到您添加的新小部件不完全位于
    文本(“A”)
    下方,有一些内容将其包裹起来,高度为
    100
    ,这就是正在绘制的
    容器。