Introduction
Micro interactions are the short, focused animations that give apps personality and signal state changes. In Flutter, TweenSequence is an underused tool that lets you compose multiple tweens with precise timing and easing to craft polished micro interactions — think button feedback, pull-to-refresh peaks, or subtle haptics-synced bounces. This article demonstrates how to use TweenSequence for complex, fine-grained motion without adding additional controllers or heavy code.
Why TweenSequence Works For Micro Interactions
TweenSequence composes several Tween segments into one Animation driven by a single AnimationController. Each segment has a weight that represents its portion of the controller's timeline. For micro interactions you often need multiple phases (anticipation → main movement → overshoot → settle). TweenSequence maps naturally to that pattern, giving per-phase easing and durations while keeping the runtime overhead minimal — one controller, one Animation per property.
Key points:
Weights act like relative durations: bigger weight = longer time.
Each Tween can have its own curve by wrapping it in a CurveTween.
Use many short segments for highly tuned motion; use fewer segments for simpler feedback.
Building A Compound Bounce With TweenSequence
A common micro interaction is a compound bounce: a quick squash, rapid overshoot, and a settle. Here is a concise TweenSequence for scale that captures those phases.
final controller = AnimationController(vsync: vsync, duration: Duration(milliseconds: 420));
final scale = TweenSequence<double>([
TweenSequenceItem(tween: Tween(begin: 1.0, end: 0.92).chain(CurveTween(curve: Curves.easeOut)), weight: 20),
TweenSequenceItem(tween: Tween(begin: 0.92, end: 1.08).chain(CurveTween(curve: Curves.easeOut)), weight: 35),
TweenSequenceItem(tween: Tween(begin: 1.08, end: 1.0).chain(CurveTween(curve: Curves.elasticOut)), weight: 45),
]).animate(controller);
Use this scale animation in an AnimatedBuilder or a Transform.scale around the widget. Trigger controller.forward(from: 0) on tap. The chained tweens precisely control each micro-phase: the initial squash is short, the overshoot is longer, and the settle uses an elastic curve for natural damping.
Chaining Color And Scale For Button Feedback
Micro interactions are more convincing when multiple properties change together. Create separate TweenSequence animations for each property but drive them with the same controller and (optionally) different curve chains. That ensures perfectly synchronized multi-property motion with different perceived timings.
Example pattern:
Scale uses fast-weighted segments for crisp physical feedback.
Color uses a slower, subtler sequence to indicate state change.
Shadow or elevation can follow scale with a slight delay by shifting weights.
Short snippet demonstrating two sequences driven by one controller:
final colorAnim = TweenSequence<Color?>([
TweenSequenceItem(tween: ColorTween(begin: base, end: highlight), weight: 30),
TweenSequenceItem(tween: ColorTween(begin: highlight, end: base), weight: 70),
]).animate(controller);
Then in build: wrap the child with Transform.scale(scale: scale.value) and DecoratedBox using colorAnim.value. This approach keeps the implementation simple and consistent: one controller, many derived animations.
Performance And Best Practices
Keep these constraints in mind when using TweenSequence in production mobile development:
Single Controller: Reuse a single AnimationController per logical interaction; do not create controllers frequently in build().
Lightweight Tweens: TweenSequence is cheap; the work is in painting. Avoid animating expensive layout changes. Prefer transforms, opacity, and color where possible.
Weights Over Durations: Use weights to adjust relative timing so you can change the overall duration in one place without recalculating segment durations.
Curves Per Segment: Chain CurveTween where you need different easing per phase instead of wrapping the whole animation in a single curve.
Test On Device: Small timing differences are more obvious on physical devices. Tune weights and curves using quick iterations on a phone.
Edge cases:
If you need separate pause windows or event-driven transitions inside the animation, consider using Future.delayed with controller control or split into two controllers. TweenSequence is best for contiguous phase-based motion.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
TweenSequence is a precise, low-overhead way to craft multi-phase micro interactions in Flutter. By composing short tweens with weights and per-segment curves, you can create natural-feeling bounces, coordinated color/scale feedback, and other polished motions driven by one controller. Start by modeling the physical phases of your interaction, map them to tween segments, tune weights and curves, and keep animations lightweight for mobile performance.