이 문서는 Advanced Android in Kotlin 03.1: Property Animation 코드랩에 대한 정리 문서입니다.
위치, 크기, 회전, 반투명도를 제어하는 다양한 View 속성들에 대해서 알아보자
val animator = ObjectAnimator.ofFloat(VIEW_ID, View.ROTATION, -360f, 0f)
// 360도에서 0도로 회전시키는 로직, view가 360도 회전한다.
animator.start()
// 애니메이션을 실행시킴, 300ms 내에 수행
// 시간을 조정하고 싶다면 duration 필드를 변경.
animator.duration = 1000
// 애니메이션이 멈추기도 전에 다시 애니메이션을 실행시키면 기본 설정 값으로 돌아감
// 이런 불연속 동작을 'jank' 현상이라고 함. 원하는 동작이 아닌 애니메이션이 멈출 수 있음
// 이런 동작을 막기 위해 애니메이션의 action에 따른 callback이 존재.
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) {
rotateButton.isEnabled = false
}
override fun onAnimationEnd(animation: Animator?) {
rotateButton.isEnabled = true
}
})
// animator에 콜백을 지정하고, 애니메이션 시작 / 끝 콜백 함수에 버튼 enabled 값을 설정
// animator.start() 를 시작하지 못하게 함
val animator = ObjectAnimator.ofFloat(star, View.TRANSLATION_X, 200f)
animator.start()
// 별이 오른쪽으로 200 픽셀만큼 이동하는 로직
// 한 방향으로만 이동하도록 설정되었음. 원래대로 돌리기 위해서는 repeat 관련 기능을 이용
val animator = ObjectAnimator.ofFloat(star, View.TRANSLATION_X, 200f)
animator.repeatCount = 1
animator.repeatMode = ObjectAnimator.REVERSE
animator.start()
// Rotate 형태와는 다르게 움직이는 길이만 받음
// 따라서 Rotate 형태는 버튼을 다시 누르면 기본 설정 값으로 돌아가지만
// Translating의 경우에는 end 값만 받아서 중간에서 재 시작함.
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) {
view.isEnabled = false
}
override fun onAnimationEnd(animation: Animator?) {
view.isEnabled = true
}
})
// 동일하게 버튼이 개입하게 하지 못하도록 button의 enabled 값을 설정한다.
// 크기를 늘리기 위해서는 X, Z 축 값을 이용하여 확장
// 단일 축으로 확장하는 경우는 거의 없음
// 늘어나는 것이 아닌 확장되는 형태로 확인하기 위해서 x, z 축을 동시에 늘리는 경우가 많음
val scaleX = PropertyValuesHolder.ofFloat(View.SCALE_X, 4f)
val scaleY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 4f)
// PropertyValuesHolder를 이용, 여러 개를 모아 ObjectAnimator를 제작할 수 있음.
val animator = ObjectAnimator.ofPropertyValuesHolder(star, scaleX, scaleY)
// 만들어 둔 PropertyValuesHolder를 ofPropertyValuesHolder 라는 함수를 이용해 적용
// ofPropertyValuesHolder 를 이용하면, 단일로 동작하지 않고 병렬적으로 동시에 애니메이트 됨
animator.repeatCount = 1
animator.repeatMode = ObjectAnimator.REVERSE
animator.start()
// Translating 과 같은 형태로, 확장되는 크기 (end) 값만 받음
// 따라서 repeat 이용해 이전으로 돌려놓는 로직 작성
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) {
view.isEnabled = false
}
override fun onAnimationEnd(animation: Animator?) {
view.isEnabled = true
}
})
// 동일하게 버튼이 개입하게 하지 못하도록 button의 enabled 값을 설정한다.
// Fading은 View의 alpha 값을 이용하여 변경
// 값이 0에 가까울 수록 투명하고, 1에 가까울 수록 불투명함
val animator = ObjectAnimator.ofFloat(star, View.ALPHA, 0f)
// alpha animation 1f -> 0f
animator.repeatCount = 1
animator.repeatMode = ObjectAnimator.REVERSE
animator.disableViewDuringAnimation(fadeButton)
animator.start()
// 공통되는 버튼이 개입하지 못하도록 하는 로직은 미 작성
// ObjectAnimator는 어떤 속성이든 액세스 할 수만 있다면 모두 애니메이션화 할 수 있음
var animator =
ObjectAnimator.ofArgb(star.parent, "backgroundColor", Color.BLACK, Color.RED)
// star.parent 값을 받고, backgroundColor에 접근, 검은색 -> 빨간색 으로 변경되는 애니메이션
animator.setDuration(500)
animator.repeatCount = 1
animator.repeatMode = ObjectAnimator.REVERSE
animator.disableViewDuringAnimation(colorizeButton)
animator.start()
Interpolator
AnimatorSet
// AnimatorSet - 여러 애니메이터를 하나로 묶어 병렬로 실행할 수 있도록 함
val set = AnimatorSet()
set.playTogether(mover, rotator /* etc */ )
// 마찬가지로 AnimatorSet도 AnimatorListenerAdapter 를 이용
// Start / End 시점 등에서 Callback 처리가 가능.