Animation là một khái niệm rất mạnh mẽ và quan trọng trong Flutter. Chúng ta không thể tưởng tượng bất kỳ ứng dụng di động nào không có hình ảnh động. Khi bạn chạm vào một nút hoặc chuyển từ trang này sang trang khác, tất cả đều là hình ảnh động. Ảnh động nâng cao trải nghiệm người dùng và làm cho các ứng dụng tương tác hơn.

Flutter cung cấp hỗ trợ tuyệt vời cho animation và có thể tách animation thành hai danh mục chính, được đưa ra dưới đây:

  • Tween Animation
  • Animation dựa trên vật lý

1. Tween animation

Đây là hình thức rút gọn của in-betweening . Trong animation tween, bắt buộc phải xác định điểm đầuđiểm cuối của animation. Nó có nghĩa là animation bắt đầu với giá trị bắt đầu, sau đó đi qua một loạt các giá trị trung gian và cuối cùng đạt đến giá trị kết thúc. Nó cũng cung cấp dòng thời gian và đường cong, xác định thời gian và tốc độ của quá trình chuyển đổi. Framework cụ cung cấp tính toán về cách chuyển đổi từ điểm đầu và điểm cuối.

1.1 Thí dụ

ColorTween {  
    begin: color.green,  
    end: color.blue,  
} 

2. Animation dựa trên vật lý

Đây là một loại animation cho phép bạn tạo ra một tương tác ứng dụng giống như thực tếtương tác . Nó mô phỏng animation / chuyển động trong thế giới thực, chẳng hạn như bạn muốn tạo animation cho một widget như spring, falling, or swinging with gravity. Do đó, nó là một animation động để đáp ứng với đầu vào / chuyển động của người dùng. Ví dụ đơn giản nhất là thời gian bay, và quãng đường di chuyển được tính theo định luật vật lý.

Flutter cung cấp hai loại kỹ thuật cho animation. Các kỹ thuật này là:

  1. Implicit Animation
  2. Explicit Animation

Hình dưới đây mô tả hệ thống phân cấp animation trong Flutter và giải thích rõ ràng hơn về animation ngầm và rõ ràng.

Bây giờ, chúng ta sẽ xem cách chúng ta có thể tạo animation rõ ràng trong Flutter. Chủ yếu có ba trụ cột của animation, được đưa ra dưới đây:

  1. Ticker
  2. Animation Class
  3. AnimationController

2.1. Ticker

Ticker là một lớp gửi tín hiệu ở một khoảng thời gian đều đặn, tức là khoảng 60 lần mỗi giây. Bạn có thể hiểu điều đó bằng đồng hồ của mình, đồng hồ này hoạt động đều đặn. Tại mỗi lần đánh dấu, Ticker cung cấp một phương thức gọi lại với khoảng thời gian kể từ lần đánh dấu đầu tiên vào mỗi giây, sau khi nó được bắt đầu. Ngay cả khi các mã bắt đầu vào các thời điểm khác nhau, nó luôn được đồng bộ hóa tự động. Lý do đằng sau điều này là các mã cho thời gian trôi qua của chúng so với lần đánh dấu đầu tiên sau khi nó được bắt đầu.

3. Animation Class

Lớp Animation là khối xây dựng cốt lõi của hệ thống animation. animation không là gì khác, nhưng nó đại diện cho một giá trị (loại cụ thể) có thể thay đổi trong suốt thời gian tồn tại của animation. Trong Flutter, các widget thực hiện animation lấy một đối tượng animation làm tham số. Đối tượng Animation này cung cấp thông tin mà từ đó chúng đọc giá trị hiện tại của animation và chúng sẽ lắng nghe những thay đổi đối với giá trị đó. Lớp hoạt hình chứa hai phương thức addListener()addStatusListener() . Khi giá trị của animation thay đổi, nó sẽ thông báo cho tất cả những người nghe được thêm vào bằng addListener(). Một lần nữa, khi trạng thái của animation thay đổi, nó sẽ thông báo cho tất cả những người nghe được thêm vào bằng addStatusListener().

Các lớp Hoạt hình phổ biến nhất là:

  • Animation <double>: Nó nội suy các giá trị giữa hai số thập phân trong một khoảng thời gian nhất định.
  • Animation <Color>: Nó nội suy màu sắc giữa hai giá trị màu.
  • Animation <Size>: Nó nội suy kích thước giữa hai giá trị kích thước.

3.1 Bộ điều khiển animation

Bộ điều khiển animation là một lớp cho phép chúng ta điều khiển animation. Nó luôn tạo ra các giá trị mới bất cứ khi nào ứng dụng sẵn sàng cho một khung mới. Ví dụ, nó cho phép kiểm soát bắt đầu, dừng, chuyển tiếp hoặc lặp lại animation. Khi bộ điều khiển animation được tạo, chúng ta có thể bắt đầu xây dựng animation khác dựa trên nó, chẳng hạn như animation ngược và animation cong.

animcontroller = AnimationController(vsync: this, duration: Duration(milliseconds: 2500));  

Ở đây, tùy chọn thời lượng kiểm soát thời lượng của quá trình animation và tùy chọn vsync được sử dụng để tối ưu hóa tài nguyên được sử dụng trong animation.

Các bước cơ bản cần thiết để sử dụng AnimationController là:

Bước 1: Đầu tiên, khởi tạo một AnimationController với các tham số, chẳng hạn như thời lượng và vsync.

Bước 2: Thêm các trình nghe cần thiết như addListener() hoặc addStatusListener().

Bước 3: Bắt đầu animation.

Bước 4: Thực hiện hành động trong phương thức gọi lại của trình nghe (ví dụ: setState).

Bước 5: Cuối cùng, loại bỏ animation.

Chúng ta hãy xem một ví dụ animation đơn giản, sử dụng một lớp animation và bộ điều khiển animation. Ví dụ sau đây cho thấy animation tween cung cấp điểm bắt đầu và điểm cuối của animation. Mở dự án và thay thế mã sau trong tệp main.dart .

import 'package:flutter/animation.dart';  
import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  // This widget is the root of your application.  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      title: 'Flutter Animation',  
      theme: ThemeData(  
        // This is the theme of your application.  
        primarySwatch: Colors.blue,  
      ),  
      home: MyHomePage(),  
    );  
  }  
}  
class MyHomePage extends StatefulWidget {  
  _HomePageState createState() => _HomePageState();  
}  
class _HomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {  
  Animation<double> animation;  
  AnimationController animationController;  
  @override  
  void initState() {  
    super.initState();  
    animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 2500));  
    animation = Tween<double>(begin: 0.0, end: 1.0).animate(animationController);  
    animation.addListener((){  
      setState((){  
        print (animation.value.toString());  
      });  
    });  
    animation.addStatusListener((status){  
      if(status == AnimationStatus.completed){  
        animationController.reverse();  
      } else if(status == AnimationStatus.dismissed) {  
        animationController.forward();  
        }  
      });  
      animationController.forward();  
    }  
  @override  
  Widget build(BuildContext context) {  
    return Center(  
      child: AnimatedLogo(  
        animation: animation,  
      )  
    );  
  }  
}  
class AnimatedLogo extends AnimatedWidget {  
  final Tween<double> _sizeAnimation = Tween<double> (begin: 0.0, end: 500.0);  
  AnimatedLogo({Key key, Animation animation}):super(key: key, listenable: animation);  
  @override  
  Widget build(BuildContext context) {  
    final Animation<double> animation = listenable;  
    return Transform.scale(  
      scale: _sizeAnimation.evaluate(animation),  
      child: FlutterLogo(),  
    );  
  }  
} 

Đầu ra

Khi bạn chạy ứng dụng trong Android Studio , bạn sẽ nhận được đầu ra. Trong màn hình, bạn sẽ thấy logo Flutter mở rộng theo hướng tiến và ngược lại.

4. Curved Animation

animation cong rất hữu ích khi bạn cần áp dụng một đường cong phi tuyến tính với một đối tượng animation. Do đó, nó xác định tiến trình của animation là một đường cong phi tuyến tính.

4.1 Cú pháp:

CurvedAnimation(parent: animationController, curve: Curves.bounceOut));  

Hãy để chúng ta hiểu nó với ví dụ trước. Để thêm đường cong, hãy mở ứng dụng trước đó trong studio android và thêm CurvedAnimation thay vì animationController . Hoặc thay thế dòng sau:

animation = Tween<double>(begin: 0.0, end: 1.0).animate(animationController);  

Với dòng bên dưới. 

animation = Tween<double>(begin: 0.0, end: 1.0).animate(animationController);

Bây giờ, khi bạn chạy ứng dụng, bạn sẽ thấy hiệu ứng nảy với biểu tượng Flutter trong quá trình mở rộng theo hướng tiến và ngược.

5. Hero Animation

Một Hero Animation là một loại hoạt hình nơi một phần tử của một màn hình bay đến một màn hình mới khi ứng dụng đi đến trang tiếp theo. Chúng ta có thể hiểu nó với ví dụ sau, nơi một animation có một phần tử như biểu tượng / hình ảnh và khi bạn chạm vào biểu tượng, màn hình sẽ chuyển sang trang tiếp theo. Ví dụ sau đây giải thích rõ ràng hơn.

Mở ứng dụng Flutter và thay thế mã sau trong tệp main.dart .

import 'package:flutter/material.dart';  
  
void main() => runApp(MyApp());  
  
class MyApp extends StatelessWidget {  
  // This widget is the root of your application.  
  @override  
  Widget build(BuildContext context) {  
    return MaterialApp(  
      title: 'Flutter Application',  
      theme: ThemeData(  
        primarySwatch: Colors.orange,  
      ),  
      home: HeroAnimation(title: 'Hero Animation'),  
    );  
  }  
}  
  
class HeroAnimation extends StatefulWidget {  
  HeroAnimation({Key key, this.title}) : super(key: key);  
  final String title;  
  
  @override  
  _HeroAnimationState createState() => _HeroAnimationState();  
}  
  
class _HeroAnimationState extends State<HeroAnimation> {  
  
  Widget _greenRectangle() {  
    return Container(  
      width: 75,  
      height: 75,  
      color: Colors.green,  
    );  
  }  
  
  Widget _detailPageRectangle() {  
    return Container(  
      width: 150,  
      height: 150,  
      color: Colors.red,  
    );  
  }  
  
  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
      appBar: AppBar(  
        title: Text(widget.title),  
      ),  
      body: buildDemoWidget(context),  
    );  
  }  
  
  Widget buildDemoWidget(BuildContext context) {  
    return Center(  
      child: Column(  
        crossAxisAlignment: CrossAxisAlignment.start,  
        children: <Widget>[  
          SizedBox(  
            height: 30.0,  
          ),  
          ListTile(  
            leading: GestureDetector(  
              child: Hero(  
                tag: 'hero-rectangle',  
                child: _greenRectangle(),  
              ),  
              onTap: () => _gotoDetailsPage(context),  
            ),  
            title: Text('Tap on the green icon rectangle to analyse hero animation transition.'),  
          ),  
        ],  
      ),  
    );  
  }  
  
  void _gotoDetailsPage(BuildContext context) {  
    Navigator.of(context).push(MaterialPageRoute(  
      builder: (ctx) => Scaffold(  
        body: Center(  
          child: Column(  
            mainAxisAlignment: MainAxisAlignment.center,  
            children: <Widget>[  
              Hero(  
                tag: 'hero-rectangle',  
                child: _detailPageRectangle(),  
              ),  
              Text('This is a place where you can see details about the icon tapped at previous page.'),  
            ],  
          ),  
        ),  
      ),  
    ));  
  }  
}  

Đầu ra

Khi bạn chạy ứng dụng trong Android Studio, bạn sẽ nhận được màn hình sau.

Để hiển thị Hero Animation, hãy nhấn vào biểu tượng màu xanh lá cây, nó sẽ ngay lập tức bay đến một màn hình mới, nơi bạn sẽ nhận được thông tin chi tiết về mục đã chạm.

Cài ứng dụng cafedev để dễ dàng cập nhật tin và học lập trình mọi lúc mọi nơi tại đây.

Tài liệu từ cafedev:

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!