Skip to content

Commit eb339d2

Browse files
fix: 🐛 Overlay rebuild issue (#547)
- When rebuild is called it is not updating overlay properly due to builder is returning same widget so added a key.
1 parent 5074d3d commit eb339d2

File tree

4 files changed

+38
-27
lines changed

4 files changed

+38
-27
lines changed

lib/src/showcase/showcase_view.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,13 +339,16 @@ class ShowcaseView {
339339
_onComplete().then(
340340
(_) {
341341
if (!_mounted) return;
342+
// Update active widget ID before starting the next showcase
342343
_activeWidgetId = id;
343344

344345
if (_activeWidgetId! >= _ids!.length) {
345346
_cleanupAfterSteps();
346347
onFinish?.call();
347348
} else {
348-
_onStart();
349+
// Add a short delay before starting the next showcase to ensure proper state update
350+
// Then start the new showcase
351+
Future.microtask(_onStart);
349352
}
350353
},
351354
);
@@ -414,15 +417,17 @@ class ShowcaseView {
414417
if (controllerLength == 1 && isAutoScroll) {
415418
await firstController?.scrollIntoView();
416419
} else {
420+
// Setup showcases after data is updated
417421
for (var i = 0; i < controllerLength; i++) {
418422
controllers[i].setupShowcase(shouldUpdateOverlay: i == 0);
419423
}
420424
}
421425
}
422426

427+
// Cancel any existing timer before setting up a new one
428+
423429
if (autoPlay) {
424430
_cancelTimer();
425-
// Showcase is first.
426431
final config = _getCurrentActiveControllers.firstOrNull?.config;
427432
_timer = Timer(
428433
config?.autoPlayDelay ?? autoPlayDelay,

lib/src/tooltip/arrow_painter.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@
2121
*/
2222
part of 'tooltip.dart';
2323

24+
class ShowcaseArrow extends StatelessWidget {
25+
const ShowcaseArrow({
26+
super.key,
27+
required this.strokeColor,
28+
});
29+
30+
final Color strokeColor;
31+
32+
@override
33+
Widget build(BuildContext context) {
34+
return CustomPaint(
35+
painter: _ArrowPainter(
36+
strokeColor: strokeColor,
37+
),
38+
size: const Size(Constants.arrowWidth, Constants.arrowHeight),
39+
);
40+
}
41+
}
42+
2443
class _ArrowPainter extends CustomPainter {
2544
_ArrowPainter({
2645
this.strokeColor = Colors.black,

lib/src/tooltip/tooltip_widget.dart

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class _ToolTipWidgetState extends State<ToolTipWidget>
173173
: SystemMouseCursors.click,
174174
child: GestureDetector(
175175
onTap: widget.onTooltipTap,
176-
child: Center(child: widget.container ?? const SizedBox.shrink()),
176+
child: widget.container ?? const SizedBox.shrink(),
177177
),
178178
)
179179
: MouseRegion(
@@ -183,7 +183,7 @@ class _ToolTipWidgetState extends State<ToolTipWidget>
183183
child: GestureDetector(
184184
onTap: widget.onTooltipTap,
185185
child: Container(
186-
padding: widget.tooltipPadding.copyWith(left: 0, right: 0),
186+
padding: widget.tooltipPadding,
187187
decoration: BoxDecoration(
188188
color: widget.tooltipBackgroundColor,
189189
borderRadius: widget.tooltipBorderRadius ??
@@ -194,12 +194,7 @@ class _ToolTipWidgetState extends State<ToolTipWidget>
194194
children: <Widget>[
195195
if (widget.title case final title?)
196196
DefaultTooltipTextWidget(
197-
padding: (widget.titlePadding ?? EdgeInsets.zero).add(
198-
EdgeInsets.only(
199-
left: widget.tooltipPadding.left,
200-
right: widget.tooltipPadding.right,
201-
),
202-
),
197+
padding: widget.titlePadding ?? EdgeInsets.zero,
203198
text: title,
204199
textAlign: widget.titleTextAlign,
205200
alignment: widget.titleAlignment,
@@ -212,13 +207,7 @@ class _ToolTipWidgetState extends State<ToolTipWidget>
212207
),
213208
if (widget.description case final desc?)
214209
DefaultTooltipTextWidget(
215-
padding:
216-
(widget.descriptionPadding ?? EdgeInsets.zero).add(
217-
EdgeInsets.only(
218-
left: widget.tooltipPadding.left,
219-
right: widget.tooltipPadding.right,
220-
),
221-
),
210+
padding: widget.descriptionPadding ?? EdgeInsets.zero,
222211
text: desc,
223212
textAlign: widget.descriptionTextAlign,
224213
alignment: widget.descriptionAlignment,
@@ -233,10 +222,6 @@ class _ToolTipWidgetState extends State<ToolTipWidget>
233222
widget.tooltipActionConfig.position.isInside)
234223
ActionWidget(
235224
tooltipActionConfig: widget.tooltipActionConfig,
236-
outsidePadding: EdgeInsets.only(
237-
left: widget.tooltipPadding.left,
238-
right: widget.tooltipPadding.right,
239-
),
240225
alignment: widget.tooltipActionConfig.alignment,
241226
crossAxisAlignment:
242227
widget.tooltipActionConfig.crossAxisAlignment,
@@ -295,11 +280,8 @@ class _ToolTipWidgetState extends State<ToolTipWidget>
295280
if (widget.showArrow)
296281
_TooltipLayoutId(
297282
id: TooltipLayoutSlot.arrow,
298-
child: CustomPaint(
299-
painter: _ArrowPainter(
300-
strokeColor: widget.tooltipBackgroundColor,
301-
),
302-
size: const Size(Constants.arrowWidth, Constants.arrowHeight),
283+
child: ShowcaseArrow(
284+
strokeColor: widget.tooltipBackgroundColor,
303285
),
304286
),
305287
],

lib/src/utils/overlay_manager.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ class OverlayManager {
7878
ShowcaseService.instance.updateCurrentScope(scope);
7979
}
8080
_shouldShow = show;
81-
_rebuild();
8281
_sync();
8382
}
8483

@@ -131,6 +130,8 @@ class OverlayManager {
131130
_hide();
132131
} else if (!_isShowing && _shouldShow) {
133132
_show(_getBuilder);
133+
} else {
134+
_rebuild();
134135
}
135136
}
136137

@@ -177,6 +178,10 @@ class OverlayManager {
177178
);
178179

179180
return Stack(
181+
// This key is used to force rebuild the overlay when needed.
182+
// this key enables `_overlayEntry?.markNeedsBuild();` to detect that
183+
// output of the builder has changed.
184+
key: ValueKey(firstShowcaseConfig.hashCode),
180185
children: [
181186
GestureDetector(
182187
onTap: firstController.handleBarrierTap,

0 commit comments

Comments
 (0)