如何在我的 Flutter 应用程序中显示可关闭的教程叠加层?
How to display a dismissable tutorial overlay in my Flutter app?
我想在我的 Flutter 应用程序的屏幕上显示教程叠加层。我什至找到了一个很好的候选者,它几乎可以满足我的要求:那就是 https://pub.dev/packages/overlay_tutorial/ plugin. The user would press a help button on the screen, the overlay would pop up with the cut outs. I don't want anything to receive clicks though (https://github.com/TabooSun/overlay_tutorial/issues/26),但是如果用户单击屏幕上的任意位置,叠加层应该会消失。
我尝试使用 AbsorbPointer and it successfully intercepts the clicks and there's no more click through and things happening bellow the overlay. See my fork: https://github.com/CsabaConsulting/overlay_tutorial/commit/9d809d51bcf55b9c8044d07d151c696bdb55abe6 但是现在也无法点击覆盖层。
@override
Widget build(BuildContext context) {
return Stack(
children: [
AbsorbPointer(
absorbing: widget.enabled && widget.absorbPointer,
ignoringSemantics: true,
child: _OverlayTutorialBackbone(
overlayColor: widget.overlayColor,
enabled: widget.enabled,
overlayTutorialHoles: _overlayTutorialHoles,
onEntryRectCalculated: () {
_updateChildren();
},
child: widget.child,
),
),
if (widget.enabled) ...[
..._overlayTutorialHoles.entries
.map((entry) {
我需要的是 AbsorbPointer 的 onTap 或 onClick 处理程序。我可以将内容包装到 GestureDetector 中,但那样会一直拦截点击和手势。这里有什么好的解决方案?
*这个答案来自我的评论
如果将此代码粘贴到 DartPad,您会看到当一个 GestureDetector
在小部件树中位于另一个上方时,只有下方的 onTap
被执行。但是,如果较低的 GestureDetector
包裹在 AbsorbPointer
和 absorbing: true
中,那么 parent GestureDetector
才会被调用。因此,您应该能够按照我在评论中的建议进行操作。即使这不是真的,您仍然可以有条件地将 parent GestureDetector
的 onTap
设置为 null
.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool absorbing = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
GestureDetector(
onTap: () {
print('GestureDetector 1');
},
child: AbsorbPointer(
absorbing: absorbing,
child: GestureDetector(
onTap: () {
print('GestureDetector 2');
},
child: Container(
height: 200.0,
width: 200.0,
color: Colors.red,
alignment: Alignment.center,
child: Text(
'Press me and check console',
style: TextStyle(
color: Colors.white,
),
),
),
),
),
),
GestureDetector(
onTap: () {
setState(() {
absorbing = !absorbing;
});
},
child: Container(
height: 200.0,
width: 200.0,
color: Colors.blue,
alignment: Alignment.center,
child: Text(
'Change absorb\n(absorbing: $absorbing)',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
),
),
),
),
],
);
}
}
我想在我的 Flutter 应用程序的屏幕上显示教程叠加层。我什至找到了一个很好的候选者,它几乎可以满足我的要求:那就是 https://pub.dev/packages/overlay_tutorial/ plugin. The user would press a help button on the screen, the overlay would pop up with the cut outs. I don't want anything to receive clicks though (https://github.com/TabooSun/overlay_tutorial/issues/26),但是如果用户单击屏幕上的任意位置,叠加层应该会消失。
我尝试使用 AbsorbPointer and it successfully intercepts the clicks and there's no more click through and things happening bellow the overlay. See my fork: https://github.com/CsabaConsulting/overlay_tutorial/commit/9d809d51bcf55b9c8044d07d151c696bdb55abe6 但是现在也无法点击覆盖层。
@override
Widget build(BuildContext context) {
return Stack(
children: [
AbsorbPointer(
absorbing: widget.enabled && widget.absorbPointer,
ignoringSemantics: true,
child: _OverlayTutorialBackbone(
overlayColor: widget.overlayColor,
enabled: widget.enabled,
overlayTutorialHoles: _overlayTutorialHoles,
onEntryRectCalculated: () {
_updateChildren();
},
child: widget.child,
),
),
if (widget.enabled) ...[
..._overlayTutorialHoles.entries
.map((entry) {
我需要的是 AbsorbPointer 的 onTap 或 onClick 处理程序。我可以将内容包装到 GestureDetector 中,但那样会一直拦截点击和手势。这里有什么好的解决方案?
*这个答案来自我的评论
如果将此代码粘贴到 DartPad,您会看到当一个 GestureDetector
在小部件树中位于另一个上方时,只有下方的 onTap
被执行。但是,如果较低的 GestureDetector
包裹在 AbsorbPointer
和 absorbing: true
中,那么 parent GestureDetector
才会被调用。因此,您应该能够按照我在评论中的建议进行操作。即使这不是真的,您仍然可以有条件地将 parent GestureDetector
的 onTap
设置为 null
.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool absorbing = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
GestureDetector(
onTap: () {
print('GestureDetector 1');
},
child: AbsorbPointer(
absorbing: absorbing,
child: GestureDetector(
onTap: () {
print('GestureDetector 2');
},
child: Container(
height: 200.0,
width: 200.0,
color: Colors.red,
alignment: Alignment.center,
child: Text(
'Press me and check console',
style: TextStyle(
color: Colors.white,
),
),
),
),
),
),
GestureDetector(
onTap: () {
setState(() {
absorbing = !absorbing;
});
},
child: Container(
height: 200.0,
width: 200.0,
color: Colors.blue,
alignment: Alignment.center,
child: Text(
'Change absorb\n(absorbing: $absorbing)',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
),
),
),
),
],
);
}
}