flutteranimasiuiMahir3 mnt baca

Animasi Implisit: AnimatedContainer dan Temannya

Buat animasi halus tanpa AnimationController dengan AnimatedContainer, AnimatedOpacity, dan AnimatedCrossFade.

Animasi tanpa ribet

Animasi implisit adalah cara termudah membuat gerakan halus: kamu cukup mengubah nilai properti, Flutter menganimasikan perubahannya otomatis selama duration. Tidak perlu controller, tween, atau listener.

AnimatedContainer

dart
class KotakAjaib extends StatefulWidget {
  const KotakAjaib({super.key});

  @override
  State<KotakAjaib> createState() => _KotakAjaibState();
}

class _KotakAjaibState extends State<KotakAjaib> {
  bool _membesar = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        AnimatedContainer(
          duration: const Duration(milliseconds: 400),
          curve: Curves.easeInOut,
          width: _membesar ? 200 : 100,
          height: _membesar ? 200 : 100,
          decoration: BoxDecoration(
            color: _membesar ? Colors.teal : Colors.amber,
            borderRadius: BorderRadius.circular(_membesar ? 100 : 12),
          ),
        ),
        const SizedBox(height: 16),
        ElevatedButton(
          onPressed: () => setState(() => _membesar = !_membesar),
          child: const Text('Ubah'),
        ),
      ],
    );
  }
}

Satu setState mengubah width, height, warna, dan radius, semuanya teranimasi mulus. curve mengatur easing, Curves.easeInOut memberi kesan natural.

AnimatedOpacity dan AnimatedCrossFade

Untuk fade in/out pakai AnimatedOpacity:

dart
AnimatedOpacity(
  duration: const Duration(milliseconds: 300),
  opacity: _terlihat ? 1.0 : 0.0,
  child: const Text('Halo!'),
)

Untuk bertukar dua widget dengan animasi ukuran plus fade, pakai AnimatedCrossFade:

dart
AnimatedCrossFade(
  duration: const Duration(milliseconds: 300),
  crossFadeState: _login
      ? CrossFadeState.showFirst
      : CrossFadeState.showSecond,
  firstChild: const FormLogin(),
  secondChild: const FormDaftar(),
)

Ini pola bagus untuk toggle login/daftar tanpa pindah halaman.

AnimatedPadding dan AnimatedPositioned

Ada juga AnimatedPadding untuk padding dan AnimatedPositioned (khusus di dalam Stack) untuk posisi. Prinsipnya sama: ubah nilai, beri duration, biarkan Flutter yang menganimasikan.

Batasan animasi implisit

Animasi implisit cocok untuk perubahan properti sederhana yang dipicu state boolean. Untuk urutan animasi kompleks (misalnya staggered, berulang, atau dikontrol gesture), kamu butuh animasi eksplisit dengan AnimationController. Jangan memaksa animasi implisit untuk koreografi rumit, hasilnya akan kaku dan kodenya berantakan.

Catatan teknis: Animasi implisit me-rebuild widget setiap frame selama durasi animasi. Jangan menaruh widget berat (misalnya list panjang atau gambar besar) di dalam AnimatedContainer yang sering berubah, karena setiap frame me-layout ulang semuanya. Pisahkan bagian yang beranimasi dari konten berat, atau pakai RepaintBoundary untuk mengisolasi repaint.