Flutter - 点击/触摸区域如何工作?
Flutter - How tap / touch area works?
1) 如果我有这个,当我点击 child Container
它不打印 'tap':
Container(
color: Colors.red,
child: GestureDetector(
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
),
),
),
2) 如果我有这个,当我点击 child Container
它会打印 'tap':
Container(
color: Colors.red,
child: GestureDetector(
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(),
),
),
),
3) 如果我有这个,当我在文本外点击 child Container
时,它会打印 'tap':
Container(
color: Colors.red,
child: GestureDetector(
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
child: Text("A"),
),
),
),
有人可以向我解释这 3 种行为吗?
- 带有边界
(height and width)
的 Container
只不过是其他小部件进入其中的占位符。由于您没有向它提供任何 child
或任何其他 属性,例如 color
或 decoration
,因此 container
被认为是不可见的GestureDetector
.
根据官方GestureDetector文档,by default a GestureDetector with an invisible child ignores touches. this behavior can be controlled with behavior.
如果您仍然希望占位符 container
被识别为点击事件,请使用 GestureDetector
的 behavior
属性,这将告诉 GestureDetector 在容器上点击然后你会看到打印出tap
,如下:
Container(
color: Colors.red,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
),
),
),
- 在这种情况下,由于您提供了
decoration
属性 并使用了 BoxDecoration()
,它会根据其 parent 小部件提供的边界呈现一个框。所以,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
打印出来。
- 在这种情况下,由于您提供了
child
小部件作为 text
,GestureDetector
识别它,因为小部件是可见的,因此 tap
被打印,无论无论您是点击文本还是文本外部,因为 GestureDetector
本身没有大小,它依赖于 child 的大小,在本例中是 bounds
(高度和宽度)。因此,它认为整个边界区域都是可点击的,并且您可以在其中的任何位置打印 tap
事件。
希望这能回答您的问题。
首先了解 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,
),
),
),
child Container
未在屏幕上绘制任何内容,因此 GestureDetector
不允许单击。但是你会说它同时具有 width
和 height
,是的,你是对的,但它没有任何东西可以在屏幕上绘制。
如果你给它任何 color
或 decoration
,或任何 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
),
),
),
在这里你给 child 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
),
),
),
这里你给 child Container
一个 Text
,因此可以在屏幕上绘制一些东西,从而启用点击。
注意:不仅 Text
,child Container
的整个区域都会收到点击,因为 GestureDetector
直接 child
是 Container
width
和 height
设置为 100
而不仅仅是 Text
。
1) 如果我有这个,当我点击 child Container
它不打印 'tap':
Container(
color: Colors.red,
child: GestureDetector(
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
),
),
),
2) 如果我有这个,当我点击 child Container
它会打印 'tap':
Container(
color: Colors.red,
child: GestureDetector(
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(),
),
),
),
3) 如果我有这个,当我在文本外点击 child Container
时,它会打印 'tap':
Container(
color: Colors.red,
child: GestureDetector(
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
child: Text("A"),
),
),
),
有人可以向我解释这 3 种行为吗?
- 带有边界
(height and width)
的Container
只不过是其他小部件进入其中的占位符。由于您没有向它提供任何child
或任何其他 属性,例如color
或decoration
,因此container
被认为是不可见的GestureDetector
.
根据官方GestureDetector文档,by default a GestureDetector with an invisible child ignores touches. this behavior can be controlled with behavior.
如果您仍然希望占位符 container
被识别为点击事件,请使用 GestureDetector
的 behavior
属性,这将告诉 GestureDetector 在容器上点击然后你会看到打印出tap
,如下:
Container(
color: Colors.red,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => print('tap'),
child: Container(
width: 100,
height: 100,
),
),
),
- 在这种情况下,由于您提供了
decoration
属性 并使用了BoxDecoration()
,它会根据其 parent 小部件提供的边界呈现一个框。所以,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
打印出来。
- 在这种情况下,由于您提供了
child
小部件作为text
,GestureDetector
识别它,因为小部件是可见的,因此tap
被打印,无论无论您是点击文本还是文本外部,因为GestureDetector
本身没有大小,它依赖于 child 的大小,在本例中是bounds
(高度和宽度)。因此,它认为整个边界区域都是可点击的,并且您可以在其中的任何位置打印tap
事件。
希望这能回答您的问题。
首先了解 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,
),
),
),
child Container
未在屏幕上绘制任何内容,因此 GestureDetector
不允许单击。但是你会说它同时具有 width
和 height
,是的,你是对的,但它没有任何东西可以在屏幕上绘制。
如果你给它任何 color
或 decoration
,或任何 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
),
),
),
在这里你给 child 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
),
),
),
这里你给 child Container
一个 Text
,因此可以在屏幕上绘制一些东西,从而启用点击。
注意:不仅 Text
,child Container
的整个区域都会收到点击,因为 GestureDetector
直接 child
是 Container
width
和 height
设置为 100
而不仅仅是 Text
。