[Android Studio] Animation - fade in & out(나타나기), move (움직이기)
레이아웃의 visibility를 조절해 사용자가 볼 수 없게 숨기고, 나타내는 기능은 많이 사용됩니다.
이때 뿅 하고 사라지는 것이 아닌 점차 사라지는 기능을 구현해보겠습니다.
mLayout.visibility = View.INVISIBLE
위와 같은 코드는 mLayout을 찰나의 순간에 사라지게 하기 때문에 유저의 입장에서 변화를 놓칠 수 있고, 부자연스럽다는 인상을 줍니다.
Animation을 활용하면 사용자가 인식할 수 있는 시간을 주기에 자연스러운 UI를 구현할 수 있습니다.
res 에 anim이란 Directory를 만들어 xml 파일을 생성해주겠습니다.
fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:fillAfter="true"
android:duration="@android:integer/config_longAnimTime" />
- fillAfter는 Animation 종료 후에도 상태를 유지할지에 관한 값입니다.
- 이미지의 Alpha를 0부터 1까지 변화(점점 나타나도록)시킵니다.
- config_longAnimTime은 500이란 값을 가지고 있으며 이는 애니메이션이 0.5초동안 실행된다는 것을 뜻합니다.
이제 이 애니메이션을 적용해보도록 하겠습니다.
lateinit var fadeInAnim : Animation
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fadeInAnim = AnimationUtils.loadAnimation(this, R.anim.fade_in)
mLayout.startAnimation(fadeInAnim)
}
적용하는 방법은 간단합니다. Animation 객체를 생성해주고, AnimationUtils.loadAnimation() 으로 만들어두었던 fade_in.xml 파일을 로드합니다.
애니메이션을 적용하고 싶은 layout에 startAnimation() 메소드를 실행해주면 끝입니다.
애니메이션을 잘 활용하기 위해서는 애니메이션을 사용하는 시점과 종류가 중요하다고 생각합니다.
무언가 로딩할 때 Animation이 포함된 Dialog를 켜고, 로딩이 끝났을 때 Dialog를 dismiss 시키는 등의 작업이 예가 될수 있겠습니다.
fade_in 외에 자주 사용할 Animation xml 파일들입니다.
fade_out.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="@android:integer/config_longAnimTime" />
move_bottom_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<!--duration500 - 0.5초동안-->
<!--fillAfter 종료 후 상태유지-->
<translate
android:fromYDelta="0%p"
android:toYDelta="100%p"
android:duration="250"
android:repeatCount = "0"
android:fillAfter="true"/>
</set>
move_bottom_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
android:fromYDelta="100%p"
android:toYDelta="0%p"
android:duration="250"
android:repeatCount = "0"
android:fillAfter="true"/>
</set>
move_top_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
android:fromYDelta="0%p"
android:toYDelta="-100%p"
android:duration="250"
android:repeatCount = "0"
android:fillAfter="true"/>
</set>
move_top_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
android:fromYDelta="-100%p"
android:toYDelta="0%p"
android:duration="250"
android:repeatCount = "0"
android:fillAfter="true"/>
</set>
turn_horizontal.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="400"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:toXScale="-1.0"
android:toYScale="1.0" />
</set>