Skip to content

Instantly share code, notes, and snippets.

@diegoveloper
Last active February 27, 2025 16:49
Show Gist options
  • Save diegoveloper/1cd23e79a31d0c18a67424f0cbdfd7ad to your computer and use it in GitHub Desktop.
Save diegoveloper/1cd23e79a31d0c18a67424f0cbdfd7ad to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
class FadeIndexedStack extends StatefulWidget {
final int index;
final List<Widget> children;
final Duration duration;
const FadeIndexedStack({
Key key,
this.index,
this.children,
this.duration = const Duration(
milliseconds: 800,
),
}) : super(key: key);
@override
_FadeIndexedStackState createState() => _FadeIndexedStackState();
}
class _FadeIndexedStackState extends State<FadeIndexedStack>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void didUpdateWidget(FadeIndexedStack oldWidget) {
if (widget.index != oldWidget.index) {
_controller.forward(from: 0.0);
}
super.didUpdateWidget(oldWidget);
}
@override
void initState() {
_controller = AnimationController(vsync: this, duration: widget.duration);
_controller.forward();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _controller,
child: IndexedStack(
index: widget.index,
children: widget.children,
),
);
}
}
@felipecastrosales
Copy link

Using Dart 3.3.0:

class FadeIndexedStack extends StatefulWidget {
  const FadeIndexedStack({
    super.key,
    required this.index,
    required this.children,
    this.duration = const Duration(milliseconds: 800),
  });

  final int index;
  final List<Widget> children;
  final Duration duration;

  @override
  _FadeIndexedStackState createState() => _FadeIndexedStackState();
}

class _FadeIndexedStackState extends State<FadeIndexedStack>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void didUpdateWidget(FadeIndexedStack oldWidget) {
    if (widget.index != oldWidget.index) {
      _controller.forward(from: 0.0);
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  void initState() {
    _controller = AnimationController(vsync: this, duration: widget.duration);
    _controller.forward();
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
      opacity: _controller,
      child: IndexedStack(
        index: widget.index,
        children: widget.children,
      ),
    );
  }
}

@wanghui159753
Copy link

Thank you very much for your constant updates

@sgshy1995
Copy link

If you need the previous widget to fade out rather than disappear abruptly, you need to do so 😁

import 'package:flutter/material.dart';

class FadeIndexedStack extends StatefulWidget {
  const FadeIndexedStack({
    super.key,
    required this.index,
    required this.children,
    this.duration = const Duration(milliseconds: 200),
  });

  final int index;
  final List<Widget> children;
  final Duration duration;

  @override
  State<FadeIndexedStack> createState() => _FadeIndexedStackState();
}

class _FadeIndexedStackState extends State<FadeIndexedStack> with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  int _currentIndex = -1;
  int? _previousIndex;

  @override
  void didUpdateWidget(FadeIndexedStack oldWidget) {
    if (widget.index != oldWidget.index) {
      setState(() {
        _previousIndex = _currentIndex;
        _currentIndex = widget.index;
        _controller.forward(from: 0.0);
      });
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  void initState() {
    super.initState();
    _currentIndex = widget.index;
    _controller = AnimationController(vsync: this, duration: widget.duration);
    _animation = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        if (_previousIndex != null)
          FadeTransition(
            opacity:
            Tween<double>(begin: 1.0, end: 0.0).animate(_animation),
            child: IndexedStack(
              index: _previousIndex,
              children: widget.children,
            ),
          ),
        FadeTransition(
          opacity: Tween<double>(begin: 0.0, end: 1.0).animate(_animation),
          child: IndexedStack(
            index: _currentIndex,
            children: widget.children,
          ),
        ),
      ],
    );
  }
}

@tuliogd
Copy link

tuliogd commented Jan 19, 2025

Nice one, bro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment