Flutter có hai lớp animation, khác nhau ở ai điều khiển tiến trình:
Implicit animation — bạn chỉ đổi giá trị đích, Flutter tự nội suy. Đó là các widget AnimatedFoo (AnimatedContainer, AnimatedOpacity, AnimatedPadding...). Đơn giản, không cần quản lý vòng đời:
dart
AnimatedContainer(
duration: const Duration(milliseconds: 300),
width: expanded ? 200 : 100, // đổi giá trị -> tự animate
)Explicit animation — bạn tự cầm AnimationController để chủ động forward(), reverse(), repeat(), biết chính xác tiến trình và lặp/đảo chiều tùy ý. Tween ánh xạ khoảng chạy 0.0 → 1.0 của controller sang khoảng giá trị thật (màu, offset, size); CurvedAnimation bẻ cong nhịp cho tự nhiên:
dart
late final _c = AnimationController(
vsync: this, duration: const Duration(milliseconds: 300));
late final _size = Tween(begin: 100.0, end: 200.0)
.animate(CurvedAnimation(parent: _c, curve: Curves.easeOut));
// dùng với AnimatedBuilder / *Transition, nhớ _c.dispose()Chọn cái nào: cần hiệu ứng một-chiều đơn giản khi state đổi → implicit (ít code, ít lỗi).
- Cần lặp, đảo chiều, đồng bộ nhiều thuộc tính, phối theo cử chỉ, hay điều khiển chính xác tiến trình → explicit.
- Controller phải có
vsync(thường quaSingleTickerProviderStateMixin) và luôndispose()để tránh rò rỉ.