Android Transition + SharedElement
고재성
2020-05-07
Overview
안녕하세요. 언제나 늦지만 새로움을 추구하는 브랜디 MA팀에서 작년까지는 개발적인 관점에서 접근하였다면 올해는 사용자 중심적인 방향으로 브랜디의 접근성을 높이기 위해 노력하기로 마음을 먹었습니다. 물론 저만의 생각은 아닐 것이라 생각합니다. 디자인팀과의 협업을 통해 다양한 테스트와 사전 기술을 습득하였고, 디자인팀 또한 처음 시도해 보는 길을 가기 위해 늦은 밤 교육과 온라인 강의를 배우는 열정을 통해 같이 브랜디의 사용자 중심의 UX를 도전할 수 있었습니다. 현재 브랜디에 마이크로 인터렉션이 적용되었고, 이와는 별개로 개발팀에서 먼저 적용할 수 있는 Transition 화면 전환에 대해서 알아보도록 하겠습니다.
Transition
브랜디 애플리케이션 구조는 하나의 Navigation Activity로 GNB Fragment로 구현되어 있습니다. 이러한 구조에서 Transition은 크게 Fragment to Fragment로 구현해서 사용하고 있습니다.
기능을 크게 나누어서 보겠습니다.
val navOptions = NavOptions.Builder()
.setEnterAnim(R.anim.slide_in_bottom)
.setExitAnim(R.anim.fade_out)
.setPopExitAnim(R.anim.slide_out_bottom)
.setPopEnterAnim(R.anim.fade_in)
.build()
https://developer.android.com/training/transitions/start-activity?hl=ko
A 라는 Fragment 는 현재 화면
B 라는 Fragment 는 다음 화면
이라고 표현하겠습니다.
EnterAnim → B Fragment 화면이 들어오는 Animation을 설정합니다.
ExitAnim → A Fragment 화면이 이동해서 빠져가는 Animation을 설정합니다.
PopExitAnim → B Fragment 화면이 종료되는 Animation을 설정합니다.
PopEnterAnim → A Fragment 화면이 다시 돌아올 때 Animation을 설정합니다.
A Fragment 는 실행 시 아래에서 위로 슬라이드하여 화면에 출력되고,
B Fragment 는 페이드 아웃 처리가 됩니다.
A Fragment 는 종료 시 아래로 슬라이드하여 화면에서 빠져나가고,
B Fragment 는 페이드 인으로 화면에 다시 출력되게 됩니다.
Fragment to Fragment 를 통해서 위와 같은 애니메이션 효과를 확인할 수 있습니다.
Transition + SharedElement
이전에 보았던 내용을 응용해서 로그인 버튼을 A Fragment에서 다음 B Fragment 화면으로 이동하는 듯한 효과를 주는 애니메이션을 처리해보겠습니다. Shared Element에 Login Button의 View를 담아 전달하게 됩니다.
val navOptions = NavOptions.Builder()
.setEnterAnim(R.anim.fade_in)
.setExitAnim(R.anim.fade_out)
.setPopExitAnim(R.anim.fade_out)
.setPopEnterAnim(R.anim.fade_in)
.build()
navOptions 의 경우 slide in, out이 아닌 fade in, out으로 변경 하였습니다.
<Button
android:id="@+id/btnLogin"
style="@style/Button.Login"
android:text="로그인"
android:transitionName="btnLogin"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
A Fragment의 Button에 android:transitionName을 선언합니다.
그리고 같은 transitionName으로 다음 B Fragment의 Button에도 동일하게 android:transitionName 을 선언합니다.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initTransitionElements()
}
fun initTransitionElements() {
sharedElementEnterTransition = ChangeBounds().apply {
duration = 300
}
sharedElementReturnTransition = ChangeBounds().apply {
duration = 300
}
}
B Fragment에 위와 같이 선언합니다.
sharedElementEnterTransition → B Fragment의 shared element animation을 선언합니다.
sharedElementReturnTransition → A Fragment로 돌아가는 shared element animation을 선언합니다.
Fragment View의 Animation과 Shared Element를 각각 독립적으로 Animation을 적용한 샘플입니다.
Conclusion
조금 간단하게 소스로 설명해드렸습니다. 물론 이를 간단하게 적용하기까지 브랜디에서 열심히 소스를 갈고닦고 있는 개발자, 디자이너 여러분들의 도움 덕분에 많은 것을 적용하고 테스트할 수 있었습니다. 2분기를 기점으로 브랜디는 MVVM의 최종 완료와 다양한 인터랙션 적용을 통해 보다 사용자들에게 안정적이며 유저 친화적인 UX로 다가설 수 있도록 오늘도 열심히 고민하겠습니다.