뷰페이저를 사용하며 스크롤 되는 모션을 바꿔보고 싶은 욕심이 생겼다.
기존의 뷰페이저는 단순히 이미지가 이동하며 스크롤 되는 애니메이션을 가지고 있었는데, 이 애니메이션을 영상효과의 디졸브 처럼 전환하고 싶었다.
이리저리 알아보다가 해당 애니메이션이 Cross Fade라는 키워드로 불린다는걸 알았고, 해당 키워드로 조금 더 검색해보다가 Page Transformer에 대해 알게됐다.
ViewPager2에서 기본 화면 전환 애니메이션과 다른 애니메이션을 사용하고 싶을 경우 Page Transformer인터페이스를 사용해 원하는 애니메이션을 구현해 ViewPager2객체에 전달할 수 있다.
// setPagerTransformer메서드로 커스텀한 Page Transformer를 전달
binding.vpTopContentImage.setPageTransformer(CrossFadePageTransformer)
Page Transformer인터페이스는 단일 메서드인 transformPage를 가지고 있는데 이 메서드를 통해 프래그먼트간 전환시 원하는 동작을 구현한다.
transformPage메서드는 ViewPager가 스크롤 되며 전환될때 현재 페이지와 인접한 전/후의 페이지에 대해서 각각 호출된다.
즉, 스크롤을 할 경우 이전 | 현재 | 다음 과 같이 총 3번의 메서드가 호출된다.
object CrossFadePageTransformer : PageTransformer {
override fun transformPage(page: View, position: Float) { ... }
}
transformPage 메서드로 전달받는 position은 각 페이지의 현재 위치를 나타낸다. 페이지가 가운데 있을 경우 position 값은 0 이며, 왼쪽끝에서는 -1, 오른쪽 끝에서는 1로 전달된다.

따라서 스크롤시 trnasformPage 메서드는 이전 View의 position이 -1, 현재 화면의 View는 0, 다음의 View는 1로 호출된다.

이를 활용해서 페이지가 스크롤될때 다양한 효과를 구현할 수 있다.
Cross Fade효과 적용을 위해 스크롤되어도 아이템이 화면을 벗어나지 않도록 position에 따라 translateX를 조정하도록 했다.
동시에 서로 사라짐과 동시에 나타나게 할 수 있도록 alpha값도 함께 조정했다.
object CrossFadePageTransformer : PageTransformer {
override fun transformPage(page: View, position: Float) {
page.apply {
// 뷰가 화면 밖에있을경우 alpha값을 0으로 조정
if (position < -1f || position > 1f) {
alpha = 0f
return
}
// 뷰의 width값에서 움직인 position값을 빼서 화면에 뷰가 고정되어있게 만듬
translationX = page.width * -position
alpha = Math.max(0f, 1f - Math.abs(position))
translationX = -page.width * position
page.alpha = alpha
}
}
}
Cross Fade효과 말고도 다양한 효과를 적용해 볼 수 있다.

심화 과정이 끝났다...
이제 실전프로젝트만 남았다...
짤 맘에 드네요