📚

【Kotlin】ViewPager vs ViewPager2

2021/10/03に公開

最近 ViewPager を使う機会があったので調べたことを備忘録として記事にします。
AndroidXに移行すると ViewPager2 というViewPagerの改良版が使えるので2つについて書いていきます。

公式のドキュメントはこちら↓↓
ViewPager
ViewPager2

実装方法だけ知りたいよという方はこちらの記事が参考になるかと思います。
Kotlinでアプリを作ってみる(TabLayout,ViewPager,Fragment,FragmentPagerAdapter)
ViewPager2 + TabLayout + DataBinding

どっちを使うべきか?

名前からイメージがつく通り ViewPager2ViewPager の改良版で基本的に ViewPager2 を使う方が良いと思います(私見です)。

ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager.

移行ガイド より

(ちなみに、僕のプロジェクトでは ViewPager2 だと感度が良すぎる(切り替わりが速い)との意見をいただいて結局 ViewPager を使うことにしました。現状の ViewPager2(v1.0.0) だとその辺のカスタマイズができませんでした。。。)

ViewPager2 を使うには

次の2stepが必要です。

  • AndroidXに移行する
  • 依存関係を追加する
dependencies {
    implementation "androidx.viewpager2:viewpager2:1.0.0"
}

使い方は ViewPager とほとんど変わりません。
レイアウトで配置→Adapterを設定

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />

ViewPager2 だと縦向きもできます)

両者の違い

Adapter

ここが一番の違いだと思います。
具体的には下記の通りです。

ViewPager ViewPager2
PagerAdapter RecyclerView.Adapter
FragmentPagerAdapter FragmentStateAdapter
FragmentStatePagerAdapter FragmentStateAdapter

大雑把にいうと、 ViewPager2 では RecyclerView がベースになっています。
各Adapterのリンクはこちら↓↓
PagerAdapter
RecyclerView.Adapter
FragmentPagerAdapter
FragmentStatePagerAdapter
FragmentStateAdapter

TabLayoutとの連携

ViewPager では

TabLayout.setupWithViewPager()

というメソッドが用意されていましたが、ViewPager2 では使えません。。
ViewPager2 では TabLayoutMediator を使います。

you must update the code that attaches the TabLayout object to the ViewPager object. While TabLayout uses its own setupWithViewPager() method to integrate with ViewPager, it requires a TabLayoutMediator instance to integrate with ViewPager2.

移行ガイド より

TabLayoutMediator を使うためにまず Material components を使えるように依存関係を追加します。

dependencies {
    implementation "com.google.android.material:material:1.1.0-beta01"
}

実際に連携するコードは下記の通りです。

TabLayoutMediator(tabLayout, viewPager) { tab, position ->
        tab.text = "タブのタイトル"
    }.attach()

自分で試した範囲だと上記で問題なく連携できそうです。
タブのタイトルの設定がAdapterからこちらに移動してますね。
他にもいろいろ設定できそうです。

ただ、直接は関係ないのですが、 Material components のバージョンを上記のようにあげると、僕のプロジェクトの場合はデザインが崩れた箇所があったので要注意です:sob:

ViewPagerを使う時は

ちなみに ViewPager にはonResume()が呼ばれるタイミングにバグがありましたが、Adapterに BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT というフラグを設定すると解消します。

class SampleAdapter(
    fm: FragmentManager
) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
    override fun getItem(position: Int): Fragment {
        return SampleFragment.newInstance(position)
    }

    override fun getCount(): Int {
        // ...
    }
}

まとめ

以上、ざっくりですがViewPager関連で調べたことをまとめました。
サンプルコードは既に記事が上がっていたので割愛しました:bow_tone1:
リンクを貼ってあるので参考にしてみてください。
前半にも書きましたが、基本的にはViewPager2を使うのが良いと思いますが、使用感に少し違いがあるのでUI/UXデザイナーと相談しながら決めた方が良さそうです。

Discussion