After ADS ’19: Migrating to ViewPager2

AndroidDevSummit 세션 내용을 간단히 정리해봅니다.

SOUP
SOUP
Nov 6 · 5 min read
Turning the Page: Migrating to ViewPager2

ViewPager2의 부가적인 기능

기존 ViewPager에서 지원하지 않던 기능들이 ViewPager2에서는 제공되고 있다. (지원할 수 없었던 것은 아닐까? 🤔)

  • Vertical Scrolling 지원
    android:orientation="vertical"
  • RTL 지원
    android:layoutDirection="rtl"
  • Modifiable Fragment collections
  • DiffUtil
    내부적으로 RecyclerView 기반으로 구현되어 있어서,
    DiffUtil도 지원한다.
  • New developement only in ViewPager2
    앞으로는 ViewPager2에만 신규 기능이 추가된다고 한다.

따라서 ViewPager1을 사용하던 코드가 유지보수 되어야 한다면, ViewPager2로 전환하는 것을 고려해봐야 할 것 같다.

Migration Guide

전환을 고려할 수 있게 가이드가 제공되고 있다.

  • RecyclerView.Adapter를 상속하는 형태로 변경된다.
// ViewPager
class MyAdapter : PagerAdapter()

// ViewPager2
class MyAdapter : RecyclerView.Adapter<...>()
  • Item Count를 정의하는 부분이 달라진다.
// ViewPager
override fun getCount(): Int {...}
// ViewPager2
override fun getItemCount(): Int {...}
  • Fragment Adapter가 변경된다.
// ViewPager
class MyFragmentAdapter(
fm: FragmentManager
) : FragmentStatePagerAdapter(fm, ...)

// ViewPager2
class MyFragmentAdapter(
fa: FragmentActivity
) : FragmentStateAdapter(fa)
// orclass MyFragmentAdapter(
fm: FragmentManager,
l: Lifecycle
) : FragmentStateAdapter(fm, l)
  • Adapter에서 Fragment 생성하기
// ViewPager
override fun getItem(position: Int): Fragment {...}

// ViewPager2
override fun createFragment(position: Int): Fragment {...}

TabLayout와의 결합

MDC 1.1.0에서 ViewPager2와 연결할 수 있는 Component를 제공한다. 기존의 ViewPager Adapter는 fun getPageTitle(position: Int)를 구현해야 했지만, ViewPager2는 별도의 API로 Configuration을 설정할 수 있다.

// build.gradle
implementation "com.google.android.material:material:1.1.0-beta01"
// Fragment - with ViewPager
tabLayout.setupWithViewPager(viewPager)
// Fragment - with ViewPager2
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.text = "Item ${(position + 1)}"
}.attach()

얼마 전에 개인 앱에 시험삼아 ViewPagerViewPager2로 교체해보니, API가 크게 변경되지 않았지만 이름은 다 변경이 되서 약간씩 손을 봐야 했다.

개인적으로 TabLayoutMediator를 사용하는 코드가 썩 예쁘진 않은 듯 해서, 아래와 같은 코드를 추가하여 코드 개선을 시도해봤다. 참고해보세요.

interface TitleProvider {
fun getItemTitle(position: Int): CharSequence
}
fun TabLayout.setupWithViewPager2(
viewPager2: ViewPager2,
titleProvider: TitleProvider,
autoRefresh: Boolean
) {
TabLayoutMediator(this, viewPager2, autoRefresh,
TabLayoutMediator.TabConfigurationStrategy { tab, position ->
tab.text = titleProvider.getItemTitle(position)
}
).attach()
}
// Use like this
tabLayout.setupWithViewPager2(
viewPager, titleProvider = pageAdapter, autoRefresh = true)

SOUP

Written by

SOUP

Android Developer in South Korea.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade