【Kotlin/Android Studio】ViewPager2の使い方!スライドで画面遷移

この記事からわかること

  • Android Studio/KotlinViewPager2使い方
  • スライド(スワイプ)で画面遷移させる方法
  • コードページを遷移するには?
  • TabLayoutとの併用方法
  • リスナーを追加してイベントを検知する
  • RTLサポート
  • スライドをにする方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

画面をスライドさせてフラグメントを移動する方法

公式リファレンス:ViewPager2

Androidアプリで画面をスライド(スワイプ)させることで滑らかに別の画面に遷移する機能を実装するにはViewPager2を使用します。以前はViewPagerでしたが、改良されて今ではViewPager2が活用されています。

【Kotlin/Android Studio】ViewPager2の使い方!スライドで画面遷移

実装方法

流れ

  1. レイアウトファイルにViewPager2を追加
  2. FragmentStateAdapterを定義
  3. アダプターの紐付け

レイアウトファイルにViewPager2を追加

レイアウトファイルにViewPager2を設置します。この領域がスライドで画面が遷移していく領域になります。


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/container"
    tools:context=".MainActivity">

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

</androidx.constraintlayout.widget.ConstraintLayout>

FragmentStateAdapterを定義

続いてFragmentStateAdapterに準拠したAdapterクラスを用意します。中にはgetItemCountメソッドとcreateFragmentメソッドをオーバーライドします。createFragmentメソッドの中ではpositionでスライドで遷移した際の番号を受け取れるので番号に応じた遷移先のフラグメントを指定します。

class ViewPagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {

    // ページリスト
    private val fragments = listOf(
        FirstFragment(),
        SecondFragment(),
        ThirdFragment()
    )

    // ページの枚数
    override fun getItemCount(): Int = fragments.size

    // ページの遷移先
    override fun createFragment(position: Int): Fragment {
        return fragments[position]
    }
}

アダプターの紐付け

最後にviewPager2アダプターを紐付けすれば完成です。これでスライドするとフラグメントが滑らかに切り替わる実装が完了しました。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var viewPager: ViewPager2 = findViewById(R.id.pager)
    val pagerAdapter = ViewPagerAdapter(this)
    viewPager.adapter = pagerAdapter
}
【Kotlin/Android Studio】ViewPager2の使い方!スライドで画面遷移

コードでページを遷移する

スワイプだけでなくKotlinのコードからページを遷移させるにはsetCurrentItemメソッドに遷移させたいページのインデックスを渡します。2つ目の引数smoothScrollには遷移時に滑らかにスクロールさせるかどうかを真偽値で指定します。

viewPager.setCurrentItem(0, true)

スワイプでのページングを不可にする

ViewPager2意図的にスワイプしてもページングをさせないようにするにはisUserInputEnabledプロパティにfalseを渡すだけです。

viewPager2.isUserInputEnabled = false

TabLayoutと併用する

TabLayoutと併用することでページのタブを表示することが可能になります。

【Kotlin/Android Studio】ViewPager2の使い方!スライドで画面遷移

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed" />

</LinearLayout>

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var viewPager: ViewPager2
    private lateinit var tabLayout: TabLayout
    private lateinit var pagerAdapter: ViewPagerAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewPager = findViewById(R.id.pager)
        pagerAdapter = ViewPagerAdapter(this)
        viewPager.adapter = pagerAdapter

        tabLayout = findViewById(R.id.tabLayout)

        // TabLayoutMediatorを使用してページングをセットアップ
        TabLayoutMediator(tabLayout, viewPager) { tab, position ->
            // タブのテキストを設定
            tab.text = "Page ${(position + 1)}"
        }.attach()
    }   
}

リスナーを追加する

ページがスワイプされたことや遷移したことを検知するためにはregisterOnPageChangeCallbackメソッドでViewPager2.OnPageChangeCallbackを拡張したオブジェクトを生成し、その中からそれぞれのイベントを検知することが可能です。

viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageSelected(position: Int) {
        // ページが選択されたときの処理
        Log.i("viewPager", "ページが選択")
    }

    override fun onPageScrollStateChanged(state: Int) {
        // ページのスクロール状態が変化したときの処理
        Log.i("viewPager", "ページのスクロール状態が変化")
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        // ページがスクロールされたときの処理
        Log.i("viewPager", "ページがスクロールされた")
    }
})

実際に1回だけ横にスワイプしてみると以下のように「ページが選択」は1回しか呼ばれないようですが、他のログは複数回出力されたので使い方には注意が必要かもしれません。

ページのスクロール状態が変化
ページがスクロールされた
ページがスクロールされた
ページがスクロールされた
ページのスクロール状態が変化

ページがスクロールされた
〜〜〜〜〜〜〜〜〜〜〜 × 10くらい
ページがスクロールされた
ページのスクロール状態が変化

RTLのサポート

RTL(右から左)をサポートしたい場合ViewPager2android:layoutDirection="rtl"を追加します。

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layoutDirection="rtl"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />    

スライドを縦にする

スライドを縦にしたい場合はViewPager2android:orientation="vertical"を追加します。

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />    
【Kotlin/Android Studio】ViewPager2の使い方!スライドで画面遷移

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index