[Kotlin] ViewPagerとFragmentPagerAdapterでスワイプによるページの切り替え

By | 2018年1月10日

複数のページを持つAndroidアプリで、左右のスワイプによるページ切り替えを行う方法です。

ラベル(TextView)をひとつだけ持つページを2つ作り、それをスワイプで切り替える簡単なサンプルアプリの作り方を通して ViewPagerFragmentPagerAdapter、各XMLレイアウトの書き方について紹介します。

アプリ全体のレイアウト

スワイプ可能なページはViewPager(android.support.v4.view.ViewPager)の子要素として追加していきます。

そのため、アプリ全体のレイアウトを以下のようにします。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

ページはプログラム側で追加するので、ViewPagerの中身は空で構いません。

各ページのレイアウト

一つひとつのページのレイアウトの雛形を指定するXMLファイルを作ります。

res/layout に fragment.xml というXMLレイアウトファイルを新しく作成し、中身を以下のように編集してください。

fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="100dp"
        android:textSize="64dp"
        android:text="defaultText" />

</RelativeLayout>

画面にラベルが一つだけ表示されるレイアウトです。

各ページ(Fragment)のレイアウトXML

後ほど defaultText の部分は、ページ番号に応じたテキストになるようにプログラムで書き換えられるようにします。

スワイプ動作のプログラム

2つのページ(Fragment)をスワイプで切り替える動作を行うためのプログラム(Kotlin)です。

package com.example.test.testproject

import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentActivity
import android.support.v4.app.FragmentPagerAdapter
import android.support.v4.app.FragmentManager
import android.support.v4.view.ViewPager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView

const val LABEL_TEXT_KEY = "labelText"

class MainActivity : FragmentActivity() {

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

        // アプリ全体のページビュー
        val pager : ViewPager = this.findViewById(R.id.pager)

        // 下記のページアダプターを設定
        val fragmentManager : FragmentManager = supportFragmentManager
        val adapter = MyPageAdapter(fragmentManager)
        pager.adapter = adapter
    }
}

// 各ページ(Fragment)をXMLレイアウトから作成
class MyFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View {

        val layout = inflater?.inflate(R.layout.fragment, container, false)

        // テキスト情報を取り出す
        val bundle : Bundle = arguments
        val labelText : String = bundle.get(LABEL_TEXT_KEY) as String

        // ラベルにテキストを設定
        val textView : TextView = layout!!.findViewById(R.id.textView)
        textView.text = labelText

        return layout
    }
}

// ページ数やページの情報を設定するFragmentPagerAdapter
class MyPageAdapter(fm : FragmentManager) : FragmentPagerAdapter(fm) {

    // 各ページの情報
    override fun getItem(position: Int): Fragment {

        val fragment : MyFragment = MyFragment()

        // 各ページに渡すテキスト情報を設定
        val bundle : Bundle = Bundle()
        bundle.putString(LABEL_TEXT_KEY, "Page" + position)
        fragment.arguments = bundle

        return fragment
    }

    // ページ数
    override fun getCount(): Int {
        return 2
    }
}

全ページの管理を行うためのクラス MyPageAdapter と、各ページを作成するクラス MyFragment を追加しています。

MyPageAdapter

FragmentPagerAdapter を継承した MyPageAdapter は、以下2つのメソッドを必ずオーバーライドします。

  • getItem(position: Int): Fragment
  • getCount(): Int

getItem では、各ページの情報を設定します。引数 position にはページの番号(0から)が含まれます。

getCount は、ページ数を設定するメソッドです。今回の例では2ページとしたので 2 を返しています。

MyFragment

先ほど作成したXMLレイアウト(fragment.xml)を読み込んで各ページを作成する処理を行っています。

MyPageAdapter で設定したラベルテキストをここで読み込んで設定を行います。

サンプルアプリの実行結果

以上のファイルとプログラムからなるアプリを実行すると、まず以下の画面が現れます。

スワイプでページを切り替えるサンプルアプリの実行例1

右にスワイプすると、次の画面がスムーズに現れます。

スワイプで切り替わる画面

スワイプが終わると、次の画面に完全に切り替わります。

2ページ目にスワイプで切り替えた様子

さらに右にスワイプしようとすると、最後のページなので画面右にスワイプできないことを表すインジケータが表示されます。

スワイプできないことを意味するインジケータ

以上、ViewPagerとFragmentPagerAdapterでスワイプによるページの切り替えを行うアプリの例でした。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*