Hoạt ảnh trong ứng dụng di động làm cho chúng sống động và phản hồi nhanh, hướng sự chú ý của người dùng và cải thiện nhận thức về giao diện. Trong bài viết này, chúng ta sẽ tìm hiểu các loại hoạt ảnh chính trong iOS và Android: Property Animation, View Animation, UIKit Dynamics, Core Animation, Lottie, Rive, Spring Animation, Hero Animation và Shared Element Transition. Tài liệu sẽ giúp các nhà phát triển mới bắt đầu hiểu nên chọn công cụ và thư viện nào cho một tác vụ cụ thể. Chi tiết hơn — trong tài liệu chính thức của Android Animations.
Những điểm chính
Android cung cấp hai hệ thống hoạt ảnh chính: View Animation (kế thừa) và Property Animation (hiện đại). View Animation (hoặc Tween Animation) chỉ hoạt động với biểu diễn trực quan — nó thay đổi hiển thị của View nhưng không thay đổi các thuộc tính thực tế của nó (ví dụ: tọa độ nhấp chuột vẫn giữ nguyên). Property Animation, được giới thiệu trong Android 3.0, thay đổi các thuộc tính thực của đối tượng thông qua Animator — ValueAnimator, ObjectAnimator hoặc AnimatorSet.
ObjectAnimator là lớp Property Animation phổ biến nhất. Nó tạo hoạt ảnh cho một thuộc tính cụ thể của đối tượng (ví dụ: translationX, alpha, scaleY) trong một khoảng thời gian xác định với một Interpolator nhất định.
ObjectAnimator.ofFloat(myView, "translationX", 0f, 300f).apply {
duration = 500
interpolator = FastOutSlowInInterpolator()
startDelay = 200
}.start()
ValueAnimator không gắn với một đối tượng cụ thể — nó tạo ra các giá trị có thể được sử dụng cho bất kỳ thuộc tính hoặc logic tùy chỉnh nào.
View Animation được mô tả trong các tệp XML res/anim/. Bốn loại được hỗ trợ: scale, translate, rotate, alpha. Nhược điểm là hoạt ảnh không thay đổi các tham số thực của View. Đối với các hiệu ứng đơn giản (nhấp nháy, xoay), View Animation vẫn có thể áp dụng, nhưng đối với các dự án mới, Property Animation được khuyến nghị.
Jetpack Compose cung cấp API hoạt ảnh hiện đại: animateAsState, Animatable, AnimatedVisibility và AnimatedContent. Hoạt ảnh trong Compose có tính phản ứng: khi trạng thái thay đổi, hoạt ảnh tự động bắt đầu.
var expanded = remember { mutableStateOf(false) }
val size = animateAsState(
if (expanded) 200f else 50f
)
Box(
modifier = Modifier
.size(size.value, size.value)
.clickable { expanded = !expanded }
.background(Color.Blue)
)
iOS cung cấp một ngăn xếp hoạt ảnh mạnh mẽ dựa trên Core Animation — một framework cấp thấp làm việc với CALayer. UIKit được xây dựng trên Core Animation với các phương thức tiện lợi UIView.animate và UIViewPropertyAnimator.
UIView.animate là cách đơn giản nhất để tạo hoạt ảnh trong iOS. Cho phép tạo hoạt ảnh cho frame, alpha, transform, backgroundColor và các thuộc tính UIView khác.
UIView.animate(
withDuration: 0.5,
delay: 0.2,
usingSpringWithDamping: 0.6,
initialSpringVelocity: 1.0,
options: [.curveEaseInOut]
) {
myView.frame.origin.x += 300
myView.alpha = 0.5
}
UIKit Dynamics — một framework cho hoạt ảnh vật lý: trọng lực, va chạm, lò xo, lực hút. Cho phép tạo hành vi đối tượng thực tế mà không cần tính toán vật lý thủ công. Được sử dụng cho các chuyển tiếp tùy chỉnh, menu hoạt ảnh và các yếu tố trò chơi.
Core Animation (CAAnimation, CABasicAnimation, CAKeyframeAnimation) — một API cấp thấp cho hoạt ảnh CALayer. Hỗ trợ biến đổi 3D, hoạt ảnh đường dẫn (keyframe), mặt nạ và tổng hợp. SwiftUI sử dụng Core Animation bên dưới thông qua các bổ ngữ animation và withAnimation.
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.fromValue = 0
animation.toValue = CGFloat.pi * 2
animation.duration = 1.0
animation.repeatCount = .infinity
myLayer.add(animation, forKey: "rotation")
Đối với phần lớn các dự án iOS, SwiftUI với hoạt ảnh tích hợp của nó được sử dụng. Ví dụ: withAnimation bao bọc các thay đổi trạng thái trong một ngữ cảnh hoạt ảnh.
Các hoạt ảnh phức tạp (nhân vật, chuyển tiếp, bộ tải) rất khó triển khai bằng mã. Lottie và Rive giải quyết vấn đề này bằng cách cho phép các nhà thiết kế tạo hoạt ảnh trong các trình chỉnh sửa trực quan và các nhà phát triển nhúng chúng vào ứng dụng như một thành phần sẵn sàng.
Lottie — một thư viện từ Airbnb (nay là LottieFiles) hiển thị các hoạt ảnh từ Adobe After Effects được xuất sang định dạng JSON. Được hỗ trợ trên Android, iOS, Flutter, React Native và Web. Các hoạt ảnh Lottie là vector, có thể mở rộng mà không mất chất lượng và có thể được tùy chỉnh theo chương trình (tốc độ, tiến trình, màu sắc).
// Android import com.airbnb.lottie.LottieAnimationView val lottieView = findViewById<LottieAnimationView>(R.id.lottieView) lottieView.setAnimation(R.raw.loading_animation) lottieView.playAnimation()
Rive (trước đây là 2Dimensions) — một công cụ tiên tiến hơn cho hoạt ảnh vector. Không giống như Lottie, Rive hỗ trợ hoạt ảnh tương tác: trạng thái, trình kích hoạt, chuyển tiếp. Hoạt ảnh được tạo trong Rive Editor và được điều khiển trong ứng dụng thông qua State Machine. Rive phù hợp cho giao diện trò chơi, biểu tượng hoạt ảnh và chuyển tiếp phức tạp với phản hồi.
Tại IT Sectr, chúng tôi sử dụng Lottie cho các hoạt ảnh trang trí (bộ tải, thao tác thành công, trạng thái trống) và Rive cho các yếu tố tương tác của màn hình onboarding. Điều này giúp giảm thời gian phát triển hoạt ảnh lên đến 60% so với triển khai thủ công bằng UIKit hoặc Canvas.
Shared Element Transition — hoạt ảnh trong đó một phần tử (hình ảnh, văn bản, thẻ) di chuyển và biến đổi mượt mà khi chuyển tiếp giữa các màn hình. Điều này tạo ra ảo giác về tính liên tục: người dùng không "đi" đến một màn hình mới, mà "chìm vào" phần tử.
Trong Android, chuyển tiếp được triển khai thông qua ActivityOptionsCompat và các thuộc tính transitionName. FragmentTransaction hỗ trợ addSharedElement cho các chuyển tiếp trong Activity. Compose sử dụng SharedTransitionLayout với SharedContentState.
iOS không có Hero Transition tích hợp, nhưng thư viện Hero (của Luke Zhao) triển khai mẫu này trên UIKit. Chỉ cần gán id cho các phần tử trên cả hai màn hình — Hero sẽ tự động tạo chuyển tiếp mượt mà. Trong SwiftUI, hoạt ảnh chuyển tiếp được tích hợp thông qua NavigationStack và matchedGeometryEffect.
Flutter có widget Hero tích hợp với tham số tag. Khi hai trang chứa Hero có cùng tag, Flutter tự động tạo hoạt ảnh chuyển tiếp giữa chúng. Đây là một trong những cách đơn giản nhất để triển khai hoạt ảnh phức tạp trong ứng dụng di động.
Hero( tag: 'profile_avatar', child: CircleAvatar( backgroundImage: AssetImage('avatar.jpg'), radius: 50, ), )
Để hoạt ảnh trông tự nhiên, các đường cong tốc độ được sử dụng — Interpolator trong Android và Easing trong iOS. Chúng xác định tốc độ hoạt ảnh thay đổi từ đầu đến cuối như thế nào.
Android hỗ trợ một số Interpolator tích hợp: LinearInterpolator (đồng đều), AccelerateDecelerateInterpolator (chậm-nhanh-chậm), FastOutSlowInInterpolator (Material Design), OvershootInterpolator (vượt quá) và BounceInterpolator (nảy). Interpolator tùy chỉnh có thể được tạo thông qua XML hoặc lớp TimeInterpolator.
| Interpolator | Hành vi | Sử dụng |
|---|---|---|
| LinearInterpolator | Tốc độ không đổi | Chỉ báo tải, xoay vô hạn |
| FastOutSlowInInterpolator | Bắt đầu nhanh, kết thúc mượt | Material Design, xuất hiện thẻ |
| OvershootInterpolator | Vượt mục tiêu và quay lại | Phần tử nhấn mạnh, nút bấm |
| BounceInterpolator | Nảy ở cuối | Danh sách, pull-to-refresh |
Spring Animation (hoạt ảnh lò xo) mô hình hóa vật lý lò xo với các tham số damping (giảm chấn) và stiffness (độ cứng). Damping 0 — dao động vô hạn, 1 — không dao động. Độ cứng xác định tốc độ hồi phục. Spring Animation có sẵn trong iOS (UIViewPropertyAnimator với UISpringTimingParameters), Android (SpringAnimation từ physics2) và SwiftUI (spring()).
Tài liệu Spring Animation trong Android chứa các ví dụ cấu hình chi tiết.
Timeline (dòng thời gian) — cách tiếp cận trong đó hoạt ảnh được chia thành các khung hình theo thời gian. Được sử dụng cho các chuỗi phức tạp mà AnimationSet hoặc hoạt ảnh nhóm không đủ linh hoạt. Android hỗ trợ AnimatorSet, iOS — CAAnimationGroup, Flutter — Interval trong AnimationController.
Часто задаваемые вопросы
View Animation (Android) chỉ thay đổi hiển thị trực quan của View mà không thay đổi các thuộc tính thực tế (vị trí nhấp chuột không thay đổi). Property Animation thay đổi các thuộc tính thực của đối tượng, cung cấp hành vi linh hoạt và có thể dự đoán hơn. Đối với các dự án mới, hãy luôn sử dụng Property Animation.
Hero Animation là hoạt ảnh trong đó một phần tử di chuyển và biến đổi mượt mà khi chuyển tiếp giữa các màn hình, tạo ra ảo giác về tính liên tục. Được triển khai thông qua Hero (Flutter), SharedElementTransition (Android) hoặc matchedGeometryEffect (SwiftUI).
Lottie và Rive là các thư viện để hiển thị hoạt ảnh vector trong thời gian chạy. Nhà thiết kế tạo hoạt ảnh trong After Effects (Lottie) hoặc Rive Editor, xuất sang JSON và nhà phát triển nhúng nó mà không cần viết mã hoạt ảnh thủ công.
Spring Animation mô hình hóa vật lý lò xo: hoạt ảnh có độ giảm chấn tự nhiên và "sự nảy". SwiftUI và Jetpack Compose hỗ trợ hoạt ảnh spring ngay từ đầu, làm cho giao diện sống động và phản hồi nhanh hơn.
Việc lựa chọn phụ thuộc vào ngữ cảnh: FastOutSlowIn — cho sự xuất hiện của phần tử, Overshoot — cho điểm nhấn, Linear — cho chỉ báo tải, Bounce — cho danh sách. Material Design khuyến nghị các đường cong tiêu chuẩn: standard easing, deceleration easing và acceleration easing.
Tóm tắt
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.