-
Notifications
You must be signed in to change notification settings - Fork 93
Open
Description
❓ What I’m trying to do
Screen.Recording.2025-04-16.at.10.12.35.am.mov
I'm building a toggle button that changes text (like "Light" ↔ "Dark") with a smooth moveY + fadeIn animation every time the text changes. I’m using:
.moveY(begin: 20, end: 0).fadeIn()onPlay: (controller) => controller.forward(from: 0)- Unique
ValueKeyper animated widget (e.g.ValueKey('new-$_animId'))
💥 Problem
The first one or two taps animate correctly. After that:
- Only fadeIn continues to work
- The moveY animation stops completely — it either doesn't trigger or is skipped entirely
- Even though I’m using unique keys and
controller.forward(from: 0), the animation does not restart
Screen.Recording.2025-04-16.at.10.15.08.am.mov
✅ What I’ve tried
- Replacing
.slideY()with.moveY()→ same issue - Forcing widget rebuild with incremented
_animId - Logging the key + checking
onPlayfires (it does) - Rebuilding in isolation (minimal widget outside of any app context)
- Setting
animate().moveY(...).fadeIn()on a fresh widget every time
🧪 Repro Code (Minimal, Copy-Paste Ready)
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
void main() {
runApp(const MaterialApp(home: Scaffold(body: Center(child: ToggleTextDemo()))));
}
class ToggleTextDemo extends StatefulWidget {
const ToggleTextDemo({super.key});
@override
State<ToggleTextDemo> createState() => _ToggleTextDemoState();
}
class _ToggleTextDemoState extends State<ToggleTextDemo> {
String _text = 'Light';
String? _prevText;
int _animId = 0;
void _toggle() {
setState(() {
_prevText = _text;
_text = _text == 'Light' ? 'Dark' : 'Light';
_animId++; // force rebuild and re-animation
});
}
@override
Widget build(BuildContext context) {
const style = TextStyle(fontSize: 24, fontWeight: FontWeight.bold);
return GestureDetector(
onTap: _toggle,
child: SizedBox(
height: 40,
child: ClipRect(
child: Stack(
alignment: Alignment.center,
children: [
if (_prevText != null)
Text(_prevText!, key: ValueKey('old-$_animId'), style: style)
.animate(onPlay: (controller) => controller.forward(from: 0))
.moveY(begin: 0, end: -20, duration: 300.ms)
.fadeOut(duration: 300.ms),
Text(_text, key: ValueKey('new-$_animId'), style: style)
.animate(onPlay: (controller) => controller.forward(from: 0))
.moveY(begin: 20, end: 0, duration: 300.ms)
.fadeIn(duration: 300.ms),
],
),
),
),
);
}
}Metadata
Metadata
Assignees
Labels
No labels