Một vài ví dụ về animation trong Flutter

Như bạn biết, Animation trong các ứng dụng moblie giúp tăng tính trực quan, tính tương tác cho giao diện người dùng. Animation khi được sử dụng đúng cách, có thể tạo ra sự khác biệt lớn trong cách người dùng cảm nhận ứng dụng của bạn.

Với Flutter các animation được tạo bằng thư viện Animation. Chúng ta bắt đầu tìm hiểu thôi nào.

Chúng ta sẽ bắt đầu với 1 animation đơn giản nhất

Rotation animation

Bây giờ ta sẽ tạo 1 file tên là animate_widget.dart với nội dung như sau:

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

  @override
  State<AnimatedWidget> createState() => _AnimatedWidgetState();
}

class _AnimatedWidgetState extends State<AnimatedWidget>
    with TickerProviderStateMixin {
  late Animation _arrowAnimation;
  late AnimationController _arrowAnimationController;

  @override
  void initState() {
    super.initState();
    _arrowAnimationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    )..repeat();
    _arrowAnimation =
        Tween(begin: 0.0, end: pi).animate(_arrowAnimationController);
  }

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: AnimatedBuilder(
        animation: _arrowAnimationController,
        builder: (context, child) => Transform.rotate(
          angle: _arrowAnimation.value,
          child: Image.asset("assets/image.jpg"),
        ),
      ),
    );
  }
}

Trong phương thức initState()_arrowAnimationControll được khởi tạo với thời gian xảy ra của animation là 300 mili giây.

_arrowAnimation được khởi tạo với giá trị begin là 0,0 và giá trị end là π do đó, nó sẽ xoay 180 độ. (pi = π = 180°)

Trong đoạn code trên chúng ta tạo 1 image và thêm một animation cho nó. Để image có animation thì cần phải bọc nó trong 1 AnimatedBuilder widget và dùng thuộc tính Transform.rotate để có thể tạo 1 vòng tròn với góc là giá trị của _arrowAnimation.

AnimatedBuilder widget là một widget rất hữu ích khi xây dựng animation. Nó hiệu quả hơn việc gọi setState() mỗi khi có sự thay đổi giá trị của animation.

Ở đây mình có sử dụng hàm repeat() để có thể lặp đi lặp lại việc xoay tròn widget

Và để có thể sử dụng được animation thì bắt buộc phải kế thừa class TickerProviderStateMixin bằng cách thêm thuộc tính with TickerProviderStateMixin

Và cũng đừng quên dùng phương thức _arrowAnimationController.dispose() trong hàm dispose, nếu không thì sẽ bị memory leak đấy.

Scale Up, Down Animation

Chúng ta sửa lại 1 chút ở file animate_widget.dart ở trên

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

  @override
  State<AnimatedWidget> createState() => _AnimatedWidgetState();
}

class _AnimatedWidgetState extends State<AnimatedWidget>
    with TickerProviderStateMixin {
  late Animation _heartAnimation;
  late AnimationController _heartAnimationController;

  @override
  void initState() {
    super.initState();
      _heartAnimationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
    _heartAnimation = Tween(begin: 160.0, end: 200.0).animate(
      CurvedAnimation(
        curve: Curves.bounceOut,
        parent: _heartAnimationController,
      ),
    );

    _heartAnimationController.addStatusListener((AnimationStatus status) {
      if (status == AnimationStatus.completed) {
        _heartAnimationController.repeat();
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(children: [
        const SizedBox(height: 100),
        Center(
          child: AnimatedBuilder(
            animation: _heartAnimationController,
            builder: (context, child) {
              return Center(
                child: SizedBox(
                  child: Center(
                    child: Icon(
                      Icons.favorite,
                      color: Colors.red,
                      size: _heartAnimation.value,
                    ),
                  ),
                ),
              );
            },
          ),
        ),
        const Spacer(),
        InkWell(
          onTap: () {
            _heartAnimationController.forward();
          },
          child: Container(
            color: Colors.red,
            margin: const EdgeInsets.only(bottom: 30),
            padding: const EdgeInsets.all(20),
            child: const Text("Run Example"),
          ),
        )
      ]),
    );
  }
}

Ta thêm hai biến _heartAnimation và _heartAnimationController tương ứng với Animation và AnimationController .

_heartAnimationController sẽ được khởi tạo với duration là 1200 mili giây.

_heartAnimation với begin là 150 và end là 170. Tương ứng với kích thước bé nhất và lớn nhất của trái tim.

❤️

Giờ thì ta cần ghép icon trái tim với animation ở trên.

Và chúng ta có kết quả chạy như ở dưới đây

Qua bài này mình đã giới thiệu các animation đơn giản và được sử dụng nhiều trong Flutter. Cảm ơn các bạn đã theo dõi.

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like