Splash Screen Using Physics Animation

Tôi chia nó thành 2 bước

  1. Một hiệu ứng rotation xoay quanh trục (0,0) của màn hình.
  2. Tạo 1 hiệu ứng Translate xuống phía bên dưới màn hình.

Animation dựa trên vật lý là gì và sự khác biệt của nó với phần còn lại như thế nào ?

Các animation trước đây khi sử dụng chúng ta cần phải thiết lập thời gian bắt đầu và kết thúc của chúng 1 cách khá phức tạp và nếu phải xử lý nhiều animation liên tiếp thì đúng là đáng sợ.

PHYSICS ANIMATION :

  • Được hỗ trợ từ API 16

Để sử dụng thư viện animation này thì chúng ta cần add lib sau và build.gradle :

compile "com.android.support:support-dynamic-animation:25.4.0"

Bây giờ bạn sẽ ko cần phải xác định bất kì khoảng thời gian hoặc bất kì giá trị nào khác. Vì bản thân nó đã tự xác định nó rồi Có 2 loại animations được API cung cấp

1. Spring Animation:

  • Gồm các animation được điều khiển bởi 1 lò xo
  • Bạn có thể xác định được tất cả các tính chất của lực lò xo
  • API cung cấp các loại hằng số khác nhau để bạn có thể cài đặt dễ dàng Spring animation

2. Fling Animations

  • Gồm các animation được điều khiển bởi lực ma sát.
  • Có 1 động lực ban đầu và dần dần chậm lại
  • Tuân theo các luật ma sát

Ứng dụng

1. Tạo ra một Spring Force và áp dụng nó vào SpringAnimation

Khởi tạo và cài đặt SpringAnimation

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)
  • Khởi tạo SpringForce với 1 giá trị ban đầu xác định vị trí cân bằng của nó
  • Bắt đàu xác định SpringAnimation sẽ có các thông số sau :
  1. View mà bạn muốn áp dụng SpringAnimation
  2. DynamicAnimation sẽ cho chúng ta biết thuộc tính nào của chúng ta sẽ animate. Đó chính là Rotation trong trường hợp của chúng ta.

2. Thiết lập DynamicAnimation.OnAnimationEndListener

springAnim.addEndListener(object : DynamicAnimation.OnAnimationEndListener {
                override fun onAnimationEnd(animation: DynamicAnimation<out DynamicAnimation<*>>?, 
                                            canceled: Boolean, value: Float, velocity: Float) {
        //Translation code will be here
})

3. Thay đổi bố cụ sau khi kết thúc và mở activity thứ 2

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()
                }

Các bước thực hiện :

  • Đầu tiên lấy kích thước chiều rộng và chiều cao của màn hình để có thể dịch chuyển nó
  • Chúng ta sẽ sử dụng hàm animate() của Relative Layout. Nó sẽ trả về cho tôi đối tượng ViewPropertyAnimator.
  • Sau khi gọi animate(), chúng ta sẽ gọi setStartDelay để tạo thời gian delay trước khi bắt đầu Animation, Sau đó chúng ta tạo các thuộc tính translation cả 2 chiều X và Y theo tương ứng với width và height củ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 Listener vào trong ViewPropertyAnimator để lấy callback OnAnimationEnd và hiển thị Activity thứ 2 ngay khi callback OnAnimationEnd được gọi.
  • Sau đó cuối cùng ở ViewPropertyAnimator chúng ta thiết lập Interpolator và gọi start()

4. Khởi chạy Spring Animation

Sau khi kết thúc khởi tạo thì chúng ta sẽ gọi start() để bắt đầu thực thi animation

Code tham khảo

https://github.com/amanjeetsingh150/SpringBasedSplash

Tài liệu tham khảo

https://android.jlelse.eu/splash-screen-using-physics-animation-4bd98eedfe04