Flutter-点按/触摸区域如何工作?

问题描述 投票:1回答:2

1)如果我有这个,当我点击子项Container时,它不会显示“点击”:

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

2)如果我有这个,当我点击子项Container时,它会打印'tap':

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

3)如果我有这个,当我在文本外部点击子项Container时,它会打印'tap':

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

有人可以向我解释这三种行为吗?

flutter flutter-layout flutter-widget
2个回答
1
投票
  1. A Container和边界为(height and width),不过是其他小部件进入其中的占位符。由于您尚未提供任何child或任何其他属性,例如colordecoration,因此container被认为对GestureDetector不可见。

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

[如果您仍然希望将占位符container识别为轻敲事件,请使用behaviorGestureDetector属性,这将告诉GestureDetector轻按容器,然后看到tap已打印,如下所示:

Container(
          color: Colors.red,
          child: GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTap: () => print('tap'),
            child: Container(
              width: 100,
              height: 100,
            ),
          ),
        ),
  1. 在这种情况下,由于您提供了decoration属性并使用了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)
            ),
          ),

enter image description here

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

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

希望这能回答您的问题。


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不允许点击。但是您会说它既有width又有height,是的,您是对的,但是在屏幕上没有任何内容。

如果您给它提供任何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 
    ),
  ),
),

这里您给孩子Container一个Text,因此在屏幕上可以画些东西,因此可以单击。

注意:不仅Text,而且子Container的整个区域都受到点击,因为GestureDetector直接childContainer,并且widthheight设置为100,而不仅仅是Text ]。

© www.soinside.com 2019 - 2024. All rights reserved.