Tạo màn hình Splash Screen sử dụng Physics Animation
Bài đăng này đã không được cập nhật trong 7 năm
1. Giới thiệu
Là một nhà phát triển, tôi cũng giống như mọi người khác luôn luôn cố gắng tìm hiểu và nghiên cứu các tính năng hay ho của các ứng dụng Android khác và thiết kế lại các tính năng đó trên ứng dụng của tôi.
Ngày hôm qua tôi tải ứng dụng ShowBox,  Một ứng dụng streaming phim và TV.

Sau khi nhìn thấy màn hình ở trên có vẻ thú vị. Tôi quyết định làm 1 splash screen gần giống như thế này. Tôi chia hiệu ứng này thành các phần
- Một hiệu ứng rotation xoay quanh trục (0,0) của màn hình.
- Tạo 1 hiệu ứng Translate xuống phía bên dưới màn hình. Trong bài viết này, tôi sẽ giới thiệu cho mọi người về cách mà tôi làm ra màn hình splash giống như cái ảnh bên dưới

Cảm ơn Google đã giới thiệu về Physics Based Animation tại Google I/O 2017. Để tôi có thể sử dụng nó tạo ra màn hình splash ở trên.
2. Physics Based Animation là gì. Và nó khác biết thế nào so với các Animation còn lại?
Cho tới thời điểm hiện tại, thì chúng ta hay nói cách khác là những nhà phát triển Android thì cũng đã có những APIs để sử dụng Animation như Value Animators, ObjectAnimator. Khi sử dụng 2 class này chúng ta phải dùng các interpolators khác nhau để điều khiển sự thay đổi của các animations. Chúng ta bị thiếu một điều đó là mỗi khi một sự kiện animation kết thúc chúng phải trải qua những đoạn mã phực tạp. Và khi phải xử lý những animation liên tiếp nhau thì chúng ta phải đổi mặt với việc tạo ra những đoạn code khổng lồ. Và giống như bức ảnh
Ohhh my code!!!!!!

Và Bây giờ có sự xuất hiện của Physics Animation :
Google đã tạo ra những đối tượng Animation này để cung cấp trải niệm thực tế hơn cho người dùng của họ. Tất cả những animation này đều được hỗ trợ tương thích ngược đến API 16.
 Để bắt đầu sử dụng các Animation này chỉ cần thêm thư viện
Để bắt đầu sử dụng các Animation này chỉ cần thêm thư viện  physics-based-support-library vào trong file build.gradle của bạn mà thôi
compile "com.android.support:support-dynamic-animation:25.4.0"
Bây giờ bạn chẳng cần phải định nghĩa bất kỳ duration hoặc một vài thuộc tính nào đó của animation cả.  F76orce của bạn đã được tạo ra để xử lý trong nội tại animation rồi.
Physics based animation API đã cung cấp 2 kiểu Animation :
- 
Spring Animation :  Các Animation được điều khiển bởi Spring Force. Nơi tất cả các vận tốc trong animation của bạn sẽ phải phụ thuộc vào Các Animation được điều khiển bởi Spring Force. Nơi tất cả các vận tốc trong animation của bạn sẽ phải phụ thuộc vàoSpring Force. Bạn sẽ phải định nghĩa tất cả các thuộc tính củaSpring Forcebao gồm cả damping ratio và stiffness. API đã cung cấp các kiểu hằng số khác nhau để chúng ta có thể thiết lập chúng một cách dễ dàng.
- 
Fling Animations  Thuộc tính Animation của View được điều khiển bởi Friction force. Fling Animation bắt đầu bởi một momen lực ban đầu và sau đó dần dần chậm lại. Nó tuân theo các định luật ma sát là lực ma sát tỉ lệ với vận tốc của vật thể do đó nó dần dần làm chậm vật thể lại.
Trong bài viết này, tôi sẽ giới thiệu Thuộc tính Animation của View được điều khiển bởi Friction force. Fling Animation bắt đầu bởi một momen lực ban đầu và sau đó dần dần chậm lại. Nó tuân theo các định luật ma sát là lực ma sát tỉ lệ với vận tốc của vật thể do đó nó dần dần làm chậm vật thể lại.
Trong bài viết này, tôi sẽ giới thiệuSping Animation, chỉ cần thế là đã đủ để làm được màn splash screen như ban đầu tôi có ý định làm. Thôi nói nhiều quá, giờ tới thời gian code thôi các bạn nhỉ :3.
3. Bắt đầu code thôi.
1. Tạo Spring Force và triển khai nó vào trong Spring Animation
springForce = SpringForce(0f)
relative_layout.pivotX = 0f
relative_layout.pivotY = 0f
val springAnim = SpringAnimation(relative_layout, DynamicAnimation.ROTATION).apply {
      springForce.dampingRatio = SpringForce.DAMPING_RATIO_HIGH_BOUNCY
      springForce.stiffness = SpringForce.STIFFNESS_VERY_LOW
}
springAnim.spring = springForce
springAnim.setStartValue(80f)
- Ở đoạn code bên trên chúng ta đã khởi tạo Spring Forcevới một contructor định nghĩa vị trí củaForcevới giá trị float.
- Chúng ta xác định trục quay cho layout của activity là đối tượng tương đối. Nó sẽ là (0,0) bởi vì chúng ta muốn quay vòng layout về gốc tọa độ.
- Bắt đầu khởi tạo SpringAnimationcần phải cung cấp một vài tham số sau :- Cung cấp Viewmà bạn muốn sử dụngSpringAnimation.
- DynamicAnimationsẽ cho chúng ta biết thuộc tính nào của chúng ta sẽ- animate. Đó chính là- Rotationtrong trường hợp của chúng ta. Và bây giờ tôi cũng phải cảm ơn- Kotlinđã tạo ra cho chúng ta từ khóa apply và cung cấp- blockhỗ trợ chúng ta định nghĩa thuộc tính của- Spring Forcebên trong nó. Trong bài viết này tôi dùng giá trị- DAMPING_RATIO_HIGH_BOUNCYđể set Damping- ratiovà- STIFFNESS_VERY_LOWđể set cho- stiffness.- DAMPING_RATIO_HIGH_BOUNCYlà để các giao động ở mức độ cao nhất. Và stiffness được set bằng- STIFFNESS_VERY_LOWthì sẽ làm cho các đối tượng di chuyển từ từ quay lại vị trí ban đầu.
 
- Cung cấp 
- Và bây giờ cuối cùng chúng ta sẽ nói về Spring Animation. Chúng ta cùng set các thuộc tính của củaSpring Force. Chúng ta đã thực hiện và thiết lập một vài giá trị khởi đầu của animation.
2. Khởi tạo DynamicAnimation.OnAnimationEndListener :
Bây giờ chúng ta đã định nghĩ rằng layout quay quanh trục (0,0) với giá trị stiffness và damping ratio được định nghĩa trước và giờ chúng ta cần di chuyển layout xuống bên phía dưới màn hình hay sau Spring Animation kết thúc. Với mục định này. API của chúng ta đã cung cấp cho chúng ta 2 Listeners :
- OnAnimationUpdateListener : Phương thức này được sử dụng để nhận các thay đổi thuộc tính trong tiến trình chạy của animation
- OnAnimationEndListener : Phương thức này được sử dụng để thông báo sự kiện kết thúc Animation khi đã được đăng ký.
Trong ứng dụng của chúng ta, chúng ta mong muốn bắt đầu dịch chuyển layout sau khi Spring Animationkết thúc vì vậy chúng ta đăng kýOnAnimationEndListener. Sau khi kết thúcSpring Animationchúng ta sẽ dịch chuyển layout sang bước tiếp theo.
springAnim.addEndListener(object : DynamicAnimation.OnAnimationEndListener {
                override fun onAnimationEnd(animation: DynamicAnimation<out DynamicAnimation<*>>?, 
                                            canceled: Boolean, value: Float, velocity: Float) {
        //Translation code will be here
})
3. Di chuyển layout sau khi nhận được sự kiện kết thúc và mở activity thứ 2 :
Bây giờ trong OnAnimationEndListener chúng ta sẽ dùng  ViewPropertyAnimator là một class có sẵn trong android để thực hiện animation của một view chỉ với một vài vòng code ngắn.
override fun onAnimationEnd(animation: DynamicAnimation<out DynamicAnimation<*>>?, canceled: Boolean, value: Float, velocity: Float) {
      val displayMetrics = DisplayMetrics()
      windowManager.defaultDisplay.getMetrics(displayMetrics)
      val height = displayMetrics.heightPixels.toFloat()
      val width = displayMetrics.widthPixels
      relative_layout.animate()
                     .setStartDelay(1)
                     .translationXBy(width.toFloat() / 2)
                     .translationYBy(height)
                     .setListener(object : Animator.AnimatorListener {
                                   override fun onAnimationRepeat(p0: Animator?) {
                                    }
                                   override fun onAnimationEnd(p0: Animator?) {
                                     val intent = Intent(applicationContext, MainActivity::class.java)
                                     finish()
                                     startActivity(intent)
                                     overridePendingTransition(0, 0)
                                    }
                                  override fun onAnimationCancel(p0: Animator?) {
                                   }
                                override fun onAnimationStart(p0: Animator?) {
                                 }
                     })
                            .setInterpolator(DecelerateInterpolator(1f))
                            .start()
                }
Tôi bắt đầu nói về từng bước một nhé :
- Đầu tiên chúng ta lấy lấy widthvàheightcủa màn hình, để chúng ta có thể có số liệu dịch chuyển.
- Tôi sử dụng hàm animate()củaRelative Layout. Nó sẽ trả về cho tôi đối tượngViewPropertyAnimator.
- Sau khi gọi  animate(), chúng ta sẽ gọisetStartDelayđể tạo thời gian delay trước khi bắt đầuAnimation, Sau đó chúng ta tạo các thuộc tínhtranslationcả 2 chiều X và Y theo tương ứng vớiwidthvàheightcủa màn hình mà ta mới lấy được ở bên trên.
- Sau khi thiết lập các thuộc tính của Animation. Chúng ta set thêm Listenervào trongViewPropertyAnimatorđể lấy callbackOnAnimationEndvà hiển thị Activity thứ 2 ngay khi callbackOnAnimationEndđược gọi. P/s: Đừng quên thêm overridePendingTransition (0, 0) sau khi gọi startActivity(). Để báo cho Window Manager vô hiệu hóa activity transaction ở Activity thứ 2.
- Sau đó cuối cùng ở ViewPropertyAnimatorchúng ta thiết lậpInterpolatorvà gọistart().
4. Cuối cùng gọi hàm start() Sping Animation của bạn.
Bây giờ Splash Screen của bạn đã sắn sàn có thể chạy được rồi. Và bạn có thể check kết quả. Để có thể tìm hiểu tốt hơn bạn có thể tìm source code tại Github Reposity
Để có tìm hiểu nhiều bài viết hay hơn nữa bạn có thể tới link bên dưới để xem nhiều điều hay ho hơn nữa. Nguồn : https://android.jlelse.eu/splash-screen-using-physics-animation-4bd98eedfe04
All rights reserved
 
  
 