Rive: nó là gì, công cụ hoạt ảnh cho Flutter và iOS

Tác giả: IT Sectr Đã đăng: 2026-03-01 Thời gian đọc: 11 phút

Rive là công cụ tạo và phát hoạt ảnh vector tương tác, kết hợp trình chỉnh sửa hoạt ảnh và thư viện runtime cho các nền tảng di động. Không giống các định dạng thụ động, Rive hỗ trợ State Machine — logic chuyển đổi giữa các hoạt ảnh dựa trên hành động của người dùng. Theo Rive Blog (2026), công cụ này được sử dụng trong hơn 10.000 dự án, bao gồm Duolingo và Bumble. Tìm hiểu thêm về các loại hoạt ảnh khác trong hướng dẫn hoạt ảnh chung.

Các điểm chính

  • Rive — công cụ hoạt ảnh vector tương tác với trình chỉnh sửa riêng.
  • State Machine — logic trực quan chuyển đổi giữa các hoạt ảnh bằng trình kích hoạt.
  • RiveRuntime — thư viện phát cho iOS, Android, Flutter và Web.
  • RiveAnimation — widget Dart của Flutter để nhúng tệp .riv vào ứng dụng.
  • Định dạng .riv — vùng chứa nhị phân chứa hoạt ảnh và State Machine.

Rive là gì?

Rive (trước đây là Rive.app, thành lập năm 2016) là trình chỉnh sửa đồ họa và runtime đa nền tảng cho hoạt ảnh vector tương tác. Không giống After Effects + Bodymovin (Lottie), Rive cung cấp môi trường thống nhất: nhà thiết kế vẽ, tạo hoạt ảnh và cấu hình logic chuyển đổi trực tiếp trong trình chỉnh sửa. Kết quả được xuất sang tệp nhị phân .riv nặng từ 2 đến 50 KB tùy theo độ phức tạp.

Sự khác biệt chính của Rive so với các giải pháp khác là State Machine. Đó là một đồ thị trực quan nơi các nút là hoạt ảnh (Idle, Hover, Press, Active) và các chuyển đổi giữa chúng được kích hoạt bởi các trình kích hoạt (Touch, Drag, Boolean). Nhà phát triển chỉ cần gửi các trình kích hoạt trong mã, và RiveRuntime quyết định hoạt ảnh nào sẽ phát và cách chuyển đổi mượt mà giữa chúng. Theo Rive Engineering (2026), hoạt ảnh .riv trung bình với State Machine chiếm 15 KB — nhỏ hơn 5–10 lần so với tệp video tương đương.

Rive Runtime có sẵn cho Flutter, iOS (Swift), Android (Kotlin/Java), Web (WASM) và React. Kết xuất được thực hiện qua Skia (Flutter/Web), Core Graphics (iOS) hoặc Canvas (Android). Rive hỗ trợ hoạt ảnh hình dạng (Knob, Slider, Button với hình học tùy chỉnh), cho phép tạo các thành phần giao diện người dùng hoạt ảnh đầy đủ, không chỉ các hoạt ảnh trang trí.

Rive vs Lottie: so sánh các cách tiếp cận

Rive và Lottie giải quyết các nhiệm vụ khác nhau. Lottie là trình phát cho hoạt ảnh có sẵn từ After Effects, tối ưu cho các hiệu ứng trang trí thụ động. Rive là công cụ tạo hoạt ảnh tương tác với logic riêng, nơi hoạt ảnh phản ứng với hành động của người dùng. Lựa chọn phụ thuộc vào mức độ tương tác yêu cầu.

Tiêu chíRiveLottie
Trình chỉnh sửaRiêng (Rive Editor)Adobe After Effects + Bodymovin
Tương tácState Machine, trình kích hoạt, Boolean, NumberChỉ play/pause/seek
Định dạng.riv (nhị phân).json hoặc .lottie (protobuf)
Kết xuấtSkia / Core Graphics / CanvasCanvas / Core Animation / Skia
UI hoạt ảnhKnob, Slider, Button, Input (tích hợp sẵn)Không có (chỉ lớp trang trí)

Khi nào chọn Rive: nút tương tác với phản hồi nhấn, yếu tố trò chơi (nhân vật với trạng thái), công tắc hoạt ảnh, biểu tượng động phản ứng theo trạng thái. Khi nào chọn Lottie: bộ tải trước, lượt thích, màn hình chào mừng, hoạt ảnh nhấn mạnh không có logic. Đối với các dự án Flutter, Rive là lựa chọn ưu tiên nhờ tích hợp gốc với Skia và pipeline kết xuất của Flutter.

Tích hợp Rive trong Flutter (Dart)

Trong Flutter, RiveAnimation là widget chính để nhúng tệp .riv. Nó có sẵn qua gói rive (chính thức). RiveAnimation hỗ trợ các đối số: artboard (chọn bảng), animation (tên hoạt ảnh), fit, alignment, controllers (cho State Machine). Cho các cảnh tương tác, StateMachineController được sử dụng.

dart
import 'package:rive/rive.dart';

// Phát hoạt ảnh đơn giản
RiveAnimation.asset(
  'assets/animations/button.riv',
  artboard: 'Button',
  animations: const ['idle'],
  fit: BoxFit.contain,
)

// StateMachineController với trình kích hoạt
class InteractiveButton extends StatefulWidget {
  @override
  State<InteractiveButton> createState() => _InteractiveButtonState();
}

class _InteractiveButtonState extends State<InteractiveButton> {
  StateMachineController? _controller;
  SMIInput<bool>? _isPressed;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (_) => _isPressed?.value = true,
      onTapUp: (_) => _isPressed?.value = false,
      child: RiveAnimation.asset(
        'assets/animations/button.riv',
        fit: BoxFit.contain,
        onInit: (artboard) {
          _controller = StateMachineController.fromArtboard(
            artboard, 'State Machine 1',
          );
          if (_controller != null) {
            artboard.addController(_controller!);
            _isPressed = _controller!.findInput<bool>('isPressed');
          }
        },
      ),
    );
  }
}

Thực tiễn tốt nhất Flutter: tải tệp .riv bất đồng bộ qua RiveAnimation.asset (AssetBundle tích hợp sẵn). Cho danh sách (ListView), sử dụng một StateMachineController duy nhất tái sử dụng giữa các mục. Rive không còn yêu cầu import riêng — rive v0.12+ bao gồm tất cả tính năng. Cho hoạt ảnh tùy chỉnh, điều khiển RiveAnimationController trực tiếp — nó cung cấp quyền truy cập vào hoạt ảnh, pha trộn (blend) và tốc độ.

Tích hợp Rive trong iOS (Swift)

Trên iOS, RiveRuntime được đại diện bởi lớp RiveView (UIKit) và RiveViewModel (SwiftUI). Thư viện được kết nối qua Swift Package Manager. RiveView kết xuất tệp .riv qua Core Graphics và Metal, hỗ trợ 120 FPS trên màn hình ProMotion. Cho State Machine, RiveStateMachineLayer được sử dụng với ràng buộc trình kích hoạt.

swift
import RiveRuntime

// SwiftUI: RiveViewModel với hoạt ảnh
struct RiveAnimationView: View {
    @State private var isPressed = false

    var body: some View {
        RiveViewModel(fileName: "button").view()
            .frame(width: 200, height: 60)
            .gesture(
                DragGesture(minimumDistance: 0)
                    .onChanged { _ in
                        if !isPressed {
                            isPressed = true
                            // Trình kích hoạt qua State Machine
                        }
                    }
                    .onEnded { _ in
                        isPressed = false
                    }
            )
    }
}

// UIKit: RiveView với điều khiển thủ công
let riveView = RiveView()
riveView.configure(fileName: "loading", extension: "riv")
riveView.fit = .contain
riveView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(riveView)

// Quản lý State Machine
riveView.triggerInput(named: "startAnimation")

Thực tiễn tốt nhất iOS: sử dụng RiveViewModel cho SwiftUI — nó tự động quản lý vòng đời. Cho UIKit, đăng ký RiveViewDelegate để theo dõi sự kiện. Rive tiêu thụ ít CPU hơn Lottie trên iOS nhờ kết xuất qua Core Graphics. Cho hoạt ảnh trong NavigationView/UICollectionView, sử dụng tải trước qua RiveFile.preload().

Tích hợp Rive trong Android (Kotlin)

Trên Android, RiveAnimationView là View chính để nhúng hoạt ảnh .riv. Thư viện app.rive:rive-android được kết nối qua Gradle. RiveAnimationView kế thừa từ View và kết xuất qua Canvas với hỗ trợ tăng tốc phần cứng. State Machine được quản lý qua setTriggers và setInputs.

kotlin
// build.gradle.kts
implementation("app.rive:rive-android:0.9.0")

// XML layout
<app.rive.RiveAnimationView
    android:id="@+id/riveView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:rive_file="@raw/mascot"
    app:rive_artboard="Mascot"
    app:rive_animation="idle" />

// Kotlin: quản lý State Machine
import app.rive.riveandroid.RiveAnimationView
import app.rive.riveandroid.StateMachineInput

val riveView = findViewById<RiveAnimationView>(R.id.riveView)
riveView.post {
    riveView.setTriggers("hover") "> Gửi trigger vào State Machine
    riveView.setInput("speed", 1.5f)
    riveView.setInput("isActive", true)
    riveView.play()
}

// Xử lý hoàn thành hoạt ảnh
riveView.addListener(object : RiveAnimationView.RiveListener() {
    override fun onAnimationCompleted(animationName: String) {
        Log.d("Rive", "Animation $animationName completed")
    }
})

Thực tiễn tốt nhất Android: tải tệp .riv qua res/raw (tài nguyên tích hợp sẵn) hoặc assets (tải qua mạng). RiveAnimationView tự động xử lý vòng đời — không gọi play/pause thủ công trong onResume/onPause. Cho hoạt ảnh trong RecyclerView, sử dụng setOnScrollListener để tạm dừng phát khi cuộn. Theo tài liệu Rive (2026), tệp .riv lên tới 100 KB được phân tích trong 5–10 ms trên thiết bị tầm trung.

State Machine: logic chuyển đổi trong Rive

State Machine là tính năng chính của Rive giúp phân biệt nó với các định dạng hoạt ảnh thụ động. Đó là một đồ thị trực quan nơi các đỉnh là trạng thái (hoạt ảnh) và các cạnh là chuyển đổi được kích hoạt bởi trình kích hoạt. State Machine được tạo trong Rive Editor: nhà thiết kế thêm nút hoạt ảnh, kết nối chúng bằng đường và gán trình kích hoạt (Touch, Boolean, Number). Nhà phát triển chỉ cần gửi các trình kích hoạt này từ mã.

dart
// Flutter: kiểm soát hoàn toàn State Machine
import 'package:rive/rive.dart';

class RiveStateMachineWidget extends StatefulWidget {
  @override
  State<RiveStateMachineWidget> createState() => _RiveStateMachineWidgetState();
}

class _RiveStateMachineWidgetState extends State<RiveStateMachineWidget> {
  Artboard? _artboard;
  StateMachineController? _controller;
  SMIInput<bool>? _isHovered;
  SMIInput<double>? _progress;

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (_) => _isHovered?.value = true,
      onExit: (_) => _isHovered?.value = false,
      child: RiveAnimation.asset(
        'assets/interactive_icon.riv',
        onInit: (artboard) {
          _controller = StateMachineController.fromArtboard(
            artboard, 'State Machine 1',
          );
          artboard.addController(_controller!);
          _isHovered = _controller!.findInput<bool>('isHovered');
          _progress = _controller!.findInput<double>('progress');
        },
      ),
    );
  }
}

// Gửi giá trị số
SMIInput<double> speedInput = controller.findInput('speed');
speedInput?.value = scrollPosition;

Loại trình kích hoạt: Boolean — công tắc (true/false), Number — giá trị số (0.0–1.0 hoặc phạm vi tùy ý), Trigger — xung một lần (nhấn nút). Trong Rive Editor, có thể cấu hình làm mịn chuyển đổi (Transition Duration) — giá trị khuyến nghị 100–300 ms để mượt. Cho trạng thái UI phức tạp, sử dụng State Machines lồng nhau (Nested State Machines) — mỗi phần hoạt ảnh được quản lý độc lập. State Machine Rive hoạt động trên tất cả nền tảng mà không thay đổi tệp .riv — logic chuyển đổi được nhúng trong tệp, không phải trong mã ứng dụng.

Các câu hỏi thường gặp

Rive khác Lottie như thế nào?

Rive là hoạt ảnh tương tác với State Machine, trình kích hoạt và trình chỉnh sửa riêng. Lottie là phát thụ động hoạt ảnh JSON từ After Effects. Rive phù hợp cho nút, trò chơi và phần tử UI có phản ứng người dùng. Lottie dành cho hiệu ứng trang trí (bộ tải trước, lượt thích). Rive sử dụng định dạng .riv, Lottie sử dụng JSON hoặc .lottie.

Có thể sử dụng Rive mà không có State Machine không?

Có. Rive hỗ trợ phát hoạt ảnh đơn giản không cần State Machine — chỉ định animationName trong RiveAnimation.asset hoặc RiveView. Trong trường hợp này, Rive hoạt động như Lottie: hoạt ảnh lặp hoặc một lần. State Machine là lớp tùy chọn cho tương tác. Cho các dự án chỉ cần hoạt ảnh trang trí, State Machine là không cần thiết.

Rive có tương thích với Android Jetpack Compose không?

Có, qua AndroidView để nhúng RiveAnimationView vào Compose. Từ rive-android 0.9.0, có sẵn trình bao bọc Compose RiveAnimation compose() với hỗ trợ bổ từ. Cho quản lý State Machine, sử dụng remember { StateMachineHolder() }. Rive cũng hỗ trợ Compose Multiplatform trên iOS qua Compose Runtime chia sẻ.

Rive có hoạt động trên Flutter Web không?

Có, Rive hỗ trợ Flutter Web qua Skia Wasm (CanvasKit) hoặc trình kết xuất HTML. CanvasKit được khuyến nghị cho hiệu suất tối đa. Các tệp Rive được tải qua yêu cầu HTTP (RiveAnimation.network) hoặc đóng gói dưới dạng tài sản. Flutter Web với Rive hoạt động chính xác trên mọi trình duyệt hiện đại (Chrome 90+, Safari 15+, Firefox 90+).

Làm thế nào để tối ưu hiệu suất Rive trên thiết bị di động?

Giới hạn số lớp hoạt động đồng thời ở mức 20–30. Sử dụng Flat shading thay vì Gradient cho hình dạng đơn giản. Cho hoạt ảnh có văn bản, sử dụng System Text (không phải văn bản vector trong Rive Editor). Giảm thiểu số lượng hoạt ảnh Bone cho nhân vật — chúng không cần thiết cho phần tử UI. Trên thiết bị cũ, tắt bộ đệm kép: riveView.enableDoubleBuffering = false trên Android.

Tổng kết

  • Rive — hoạt ảnh vector tương tác với trình chỉnh sửa riêng và runtime cho hơn 5 nền tảng.
  • State Machine — logic chuyển đổi tích hợp giữa các hoạt ảnh bằng trình kích hoạt (Touch, Boolean, Number).
  • RiveRuntime — thư viện cho Flutter, iOS, Android, Web và React với kết xuất qua Skia/Core Graphics.
  • Định dạng .riv — vùng chứa nhị phân nặng 2–50 KB chứa hoạt ảnh và State Machine.
  • RiveAnimation (Flutter), RiveViewModel (SwiftUI), RiveAnimationView (Android) — các thành phần chính.
  • Rive phù hợp cho phần tử UI tương tác, Lottie cho hoạt ảnh trang trí thụ động.
  • Loại trình kích hoạt: Boolean (công tắc), Number (số), Trigger (xung). Thời gian chuyển đổi khuyến nghị — 100–300 ms.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm