[TIL] Page Transformer

박봉팔·2024년 2월 16일
0

Cross Fade

뷰페이저를 사용하며 스크롤 되는 모션을 바꿔보고 싶은 욕심이 생겼다.

기존의 뷰페이저는 단순히 이미지가 이동하며 스크롤 되는 애니메이션을 가지고 있었는데, 이 애니메이션을 영상효과의 디졸브 처럼 전환하고 싶었다.

이리저리 알아보다가 해당 애니메이션이 Cross Fade라는 키워드로 불린다는걸 알았고, 해당 키워드로 조금 더 검색해보다가 Page Transformer에 대해 알게됐다.


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효과 말고도 다양한 효과를 적용해 볼 수 있다.

[구글 디벨롭먼트에서 확인해보기]


오늘은 어땠나요?

심화 과정이 끝났다...

이제 실전프로젝트만 남았다...

profile
개발 첫걸음! 가보자구!

1개의 댓글

comment-user-thumbnail
2024년 2월 17일

짤 맘에 드네요

답글 달기