Skip to content

Instantly share code, notes, and snippets.

@orestesgaolin
Last active June 30, 2025 21:28
Show Gist options
  • Save orestesgaolin/e646bfa21169a4f3bf2aee632e9c59bf to your computer and use it in GitHub Desktop.
Save orestesgaolin/e646bfa21169a4f3bf2aee632e9c59bf to your computer and use it in GitHub Desktop.
import 'dart:async';
import 'package:flutter/widgets.dart';
/// Widget that delays opacity change when widget
/// appears (in) or disappears (out)
class DelayedAnimatedOpacity extends StatefulWidget {
const DelayedAnimatedOpacity({
super.key,
Duration? delayIn,
Duration? delayOut,
this.duration = const Duration(milliseconds: 500),
required this.child,
required this.visible,
}) : delayIn = delayIn ?? const Duration(milliseconds: 500),
delayOut = delayOut ?? Duration.zero;
final Duration delayIn;
final Duration delayOut;
final Duration duration;
final Widget child;
final bool visible;
@override
State<DelayedAnimatedOpacity> createState() => _DelayedAnimatedOpacityState();
}
class _DelayedAnimatedOpacityState extends State<DelayedAnimatedOpacity> {
bool visible = false;
Timer? _timer;
@override
void initState() {
super.initState();
if (widget.visible) {
_timer = Timer(widget.delayIn, () {
if (mounted) {
setState(() {
visible = true;
});
}
});
}
}
@override
void didUpdateWidget(covariant DelayedAnimatedOpacity oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.visible != visible) {
_updateVisibility(widget.visible);
}
}
void _updateVisibility(bool isVisible) {
_timer?.cancel();
final delay = isVisible ? widget.delayIn : widget.delayOut;
_timer = Timer(delay, () {
if (mounted) {
setState(() {
visible = isVisible;
});
}
});
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return IgnorePointer(
ignoring: !visible,
child: AnimatedOpacity(
duration: widget.duration,
opacity: visible ? 1 : 0,
child: widget.child,
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment