0%

Flutter'da Animasyonlar

Flutter'da kullanıcı deneyimini geliştiren animasyon teknikleri.

📅
👤CodeBros
⏱️5 dakikada okunur
FlutterAnimasyonUX
Flutter'da Animasyonlar - Blog yazısı öne çıkan görseli

Flutter'da Animasyonlar

Flutter, mobil uygulama geliştirmede zengin animasyon deneyimleri sunan güçlü bir framework'tür. Bu yazıda Flutter'da animasyon oluşturma tekniklerini detaylı şekilde inceleyeceğiz.

Flutter Animasyon Sistemi

Flutter'da animasyonlar, widget'ların zaman içinde özelliklerini değiştirmek için kullanılır. Flutter'ın animasyon sistemi esnek ve performanslı bir yapıya sahiptir.

Temel Animasyon Kavramları

1. Animation Sınıfı

class Animation<T> {
  T get value;
  AnimationStatus get status;
  void addListener(VoidCallback listener);
  void addStatusListener(AnimationStatusListener listener);
}

2. AnimationController

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,
    );
    _animation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(_controller);
  }

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

Temel Animasyon Türleri

1. Fade Animasyonu

class FadeAnimation extends StatefulWidget {
  @override
  _FadeAnimationState createState() => _FadeAnimationState();
}

class _FadeAnimationState extends State<FadeAnimation> 
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 1000),
      vsync: this,
    );
    _animation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ));
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return Opacity(
          opacity: _animation.value,
          child: Container(
            width: 200,
            height: 200,
            color: Colors.blue,
            child: Center(child: Text('Fade In')),
          ),
        );
      },
    );
  }
}

2. Slide Animasyonu

class SlideAnimation extends StatefulWidget {
  @override
  _SlideAnimationState createState() => _SlideAnimationState();
}

class _SlideAnimationState extends State<SlideAnimation> 
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<Offset> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 800),
      vsync: this,
    );
    _animation = Tween<Offset>(
      begin: Offset(-1.0, 0.0),
      end: Offset(0.0, 0.0),
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.elasticOut,
    ));
  }

  @override
  Widget build(BuildContext context) {
    return SlideTransition(
      position: _animation,
      child: Container(
        width: 200,
        height: 100,
        color: Colors.green,
        child: Center(child: Text('Slide In')),
      ),
    );
  }
}

3. Scale Animasyonu

class ScaleAnimation extends StatefulWidget {
  @override
  _ScaleAnimationState createState() => _ScaleAnimationState();
}

class _ScaleAnimationState extends State<ScaleAnimation> 
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 600),
      vsync: this,
    );
    _animation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.bounceOut,
    ));
  }

  @override
  Widget build(BuildContext context) {
    return ScaleTransition(
      scale: _animation,
      child: Container(
        width: 150,
        height: 150,
        decoration: BoxDecoration(
          color: Colors.red,
          shape: BoxShape.circle,
        ),
        child: Center(child: Text('Scale Up')),
      ),
    );
  }
}

İleri Düzey Animasyonlar

1. Staggered Animasyonlar

class StaggeredAnimation extends StatefulWidget {
  @override
  _StaggeredAnimationState createState() => _StaggeredAnimationState();
}

class _StaggeredAnimationState extends State<StaggeredAnimation> 
    with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _containerScale;
  late Animation<double> _textOpacity;
  late Animation<Color?> _containerColor;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 2000),
      vsync: this,
    );

    _containerScale = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Interval(0.0, 0.5, curve: Curves.elasticOut),
    ));

    _textOpacity = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Interval(0.3, 0.8, curve: Curves.easeIn),
    ));

    _containerColor = ColorTween(
      begin: Colors.blue,
      end: Colors.purple,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Interval(0.5, 1.0, curve: Curves.easeInOut),
    ));
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return Transform.scale(
          scale: _containerScale.value,
          child: Container(
            width: 200,
            height: 200,
            decoration: BoxDecoration(
              color: _containerColor.value,
              borderRadius: BorderRadius.circular(20),
            ),
            child: Center(
              child: Opacity(
                opacity: _textOpacity.value,
                child: Text(
                  'Staggered Animation',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

2. Custom Painter ile Animasyonlar

class CustomPainterAnimation extends StatefulWidget {
  @override
  _CustomPainterAnimationState createState() => _CustomPainterAnimationState();
}

class _CustomPainterAnimationState extends State<CustomPainterAnimation> 
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(milliseconds: 2000),
      vsync: this,
    );
    _animation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return CustomPaint(
          painter: CirclePainter(_animation.value),
          size: Size(200, 200),
        );
      },
    );
  }
}

class CirclePainter extends CustomPainter {
  final double animationValue;

  CirclePainter(this.animationValue);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..style = PaintingStyle.fill;

    final center = Offset(size.width / 2, size.height / 2);
    final radius = (size.width / 2) * animationValue;

    canvas.drawCircle(center, radius, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

Hero Animasyonları

Hero animasyonları, sayfalar arası geçişlerde ortak elementleri animate etmek için kullanılır:

// İlk sayfa
class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GestureDetector(
          onTap: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
          child: Hero(
            tag: 'hero-image',
            child: Container(
              width: 100,
              height: 100,
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.circular(50),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

// İkinci sayfa
class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Hero(
          tag: 'hero-image',
          child: Container(
            width: 200,
            height: 200,
            decoration: BoxDecoration(
              color: Colors.blue,
              borderRadius: BorderRadius.circular(20),
            ),
          ),
        ),
      ),
    );
  }
}

Animasyon Curve'leri

Flutter'da farklı animasyon curve'leri kullanabilirsiniz:

// Temel curve'ler
Curves.linear
Curves.easeIn
Curves.easeOut
Curves.easeInOut
Curves.bounceIn
Curves.bounceOut
Curves.elasticIn
Curves.elasticOut

// Custom curve
class CustomCurve extends Curve {
  @override
  double transform(double t) {
    return t * t * t; // Cubic curve
  }
}

Performans İpuçları

1. RepaintBoundary Kullanımı

RepaintBoundary(
  child: AnimatedContainer(
    duration: Duration(milliseconds: 500),
    // animation özellikleri
  ),
)

2. AnimatedBuilder Optimizasyonu

AnimatedBuilder(
  animation: _controller,
  builder: (context, child) {
    return Transform.rotate(
      angle: _controller.value * 2 * math.pi,
      child: child, // Bu child değişmeyecekse burada tanımla
    );
  },
  child: Container(
    width: 100,
    height: 100,
    color: Colors.blue,
  ),
)

Sonuç

Flutter'da animasyonlar, kullanıcı deneyimini büyük ölçüde iyileştirir. Bu yazıda gördüğümüz tekniklerle:

  • Temel animasyonlar oluşturabilir
  • Karmaşık staggered animasyonlar yapabilir
  • Custom painter ile özel animasyonlar çizebilir
  • Hero animasyonları ile sayfa geçişlerini zenginleştirebilirsiniz

Flutter'ın güçlü animasyon sistemi sayesinde, kullanıcılarınızın memnun kalacağı etkileyici uygulamalar geliştirebilirsiniz.

K
CodeBros
CodeBros - Profesyonel Yazılım Geliştirme Şirketi
Paylaş:
WhatsApp
WhatsApp