我想使用GestureDetector的onTapDown回调函数,同时还想有一个漂亮的InkWell水波纹效果。
这两个能一起使用吗?
我想使用GestureDetector的onTapDown回调函数,同时还想有一个漂亮的InkWell水波纹效果。
这两个能一起使用吗?
new Listener(
onPointerDown: (e) { print('onPointerDown'); },
child: new InkWell(
child: new Text('Tap me'),
onTap: () { print('onTap'); }
),
),
在InkWell中添加一个onTapDown处理程序可能是有意义的。
您可以通过将HitTestBehavior
传递给GestureDetector
,并将其值设置为"translucent"来使其变为“非阻塞”。
或者您可以使用Material.of(context)
自行触发它。
在 Rémi 建议将 HitTestBehavior.translucent
行为添加到您的 GestureDetector
上之后,这是我解决您问题的方法:
Material(
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onTapDown: (details) {
//Do something
},
child: InkWell(
onTap: () {},
child: Container(height: 20.0, width: 20.0, color: Colors.red),
),
),
),
我使用类似的方法来给我的InkWell
添加了onLongPressStart
和onLongPressEnd
事件。
import 'package:flutter/material.dart';
class CardPreview extends StatefulWidget {
final dynamic data;
final VoidCallback onTap;
const CardPreview(this.data, this.onTap);
CardPreview._(this.data, this.onTap);
factory CardPreview.fromData(dynamic data, VoidCallback onTap) {
return new CardPreview(data, onTap);
}
CardPreview createState() => new CardPreview(this.data, this.onTap);
}
class CardPreviewState extends State<CardPreview> {
final dynamic data;
final VoidCallback onTap;
CardPreviewState(this.data, this.onTap);
Widget buildCard() {
return Material(
color: Colors.transparent,
child: Ink(
child: InkWell(
child: null,
onTap: () {
if (this.onTap == null) {
return;
}
this.onTap();
},
),
),
);
}
@override
Widget build(BuildContext context) {
return Container(
child: buildCard(),
);
}
}
onTapDown
回调函数了https://api.flutter.dev/flutter/material/InkResponse/onTapDown.html
https://api.flutter.dev/flutter/material/InkWell/InkWell.html
不过,GestureDetector仍然比InkWell具有更多的功能,例如onSecondaryTap
。因此,在今天嵌套InkWell和GestureDetector是很有用的。
HitTestBehavior.opaque
对子父关系没有影响https://github.com/flutter/flutter/issues/18450#issuecomment-397372078
https://github.com/flutter/flutter/issues/74733#issuecomment-767859584
简而言之,HitTestBehavior.opaque
只是通过在 HitTest 中返回 true
来防止其后面的兄弟节点接收事件,以便其直接父级不会将事件传递给其下一个子级(按相反顺序),并在 HitTest 中返回 true
。(因此,其祖先后面的兄弟节点也不会接收事件。就像其祖先的行为被覆盖为 opaque 一样。)但是其祖先始终会接收事件!https://api.flutter.dev/flutter/rendering/RenderBox/hitTest.html
https://api.flutter.dev/flutter/rendering/RenderProxyBoxWithHitTestBehavior/hitTest.html(RenderProxyBoxWithHitTestBehavior
被_RenderColoredBox
使用,它是Container
的“color”)
https://api.flutter.dev/flutter/rendering/RenderProxyBoxWithHitTestBehavior/hitTestSelf.html
https://api.flutter.dev/flutter/rendering/RenderStack/hitTestChildren.html(使用defaultHitTestChildren
)
致谢:参考了https://github.com/flutter/flutter/issues/18450#issuecomment-601865975
onTap
,只有“获胜者”的回调才能触发请参见https://api.flutter.dev/flutter/widgets/GestureDetector-class.html
有些回调函数(例如onTapDown)可能会在识别器赢得竞技场之前触发,而其他回调函数(例如onTapCancel)则会在它输掉竞技场时触发。因此,上面的示例中的父检测器可能会调用一些回调函数,即使它在竞技场中输了。将GestureDetector.behavior设置为HitTestBehavior.opaque或HitTestBehavior.translucent对父子关系没有影响:两个GestureDetector都会向手势竞技场发送一个GestureRecognizer,只有一个会获胜。
onTapDown
。