LoginSignup
7
5

More than 3 years have passed since last update.

[kotlin] ViewPagerをボタンで切り替える

Posted at

今回やること

これ↓

ViewPagerを使ってフラグメントの切り替えをスワイプとボタンでできるようにする。(kotlinで書きます) OnPageChangeListenerを使います
※今回はViewPager実装済みとしてやっていくのでアダプターなどには触れません。まだ実装してないよという方はよろしければこちら参考に。

[kotlin] ViewPagerでフラグメントを切り替える

ボタンを作成

レイアウトファイルにボタンを作る。

activity_main
<?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"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/nextPageBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="次へ"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.9"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.95" />

    <Button
        android:id="@+id/prevPageBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="前へ"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.1"
        app:layout_constraintStart_toStartOf="@+id/viewPager"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.95" />

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" >

    </androidx.viewpager.widget.ViewPager>
</androidx.constraintlayout.widget.ConstraintLayout>

ViewPagerに加えて「次へ」「前へ」の2つのボタンをつける。
ボタンは全フラグメント共通で表示したいのでフラグメントのレイアウトxmlファイルではなくViewPagerを実装しているレイアウトxmlファイルにつける。

リスナーをセット

上記で作成したボタンにリスナーをセットする

MainActivity.kt
package com.example.viewpagersample

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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


        /// フラグメントのリストを作成
        val fragmentList = arrayListOf<Fragment>(
            Sample1Fragment(),
            Sample2Fragment(),
            Sample3Fragment()
        )

        /// adapterのインスタンス生成
        val adapter = SamplePagerAdapter(supportFragmentManager, fragmentList)
        viewPager.adapter = adapter

        /// ページ遷移のリスナーをセット
        nextPageBtn.setOnClickListener {
            // ページを1つ進める
            viewPager.currentItem += 1
        }
        prevPageBtn.setOnClickListener {
            // ページを1つ戻す
            viewPager.currentItem -= 1
        }
    }
}

とりあえず完成。
ただしこのままだと一番最初のぺージや最後のページでも「次へ」「前へ」ボタンが表示されるのでOnPageChangeListenerを使う

OnPageChangeListener

OnPageChangeListener: ViewPagerに用意されているメソッドの一つ

似たようなものにSimpleOnPageChangeListenerがある。こちらはimplementsしなければならないメソッドがより少なくonPageSelectedだけになっている。

上記のコードに以下を追加する。

MainActivity.kt
 /// prevBtnの初期visibility
        prevPageBtn.isVisible = false

        /// スクロール中の変更処理
        viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
            /// implementする
            override fun onPageSelected(position: Int) {
                /// btnの表示制御(端では表示しない)
                prevPageBtn.isVisible = position != 0
                nextPageBtn.isVisible = position != fragmentList.size - 1
            }

            override fun onPageScrollStateChanged(state: Int) {
            }

            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
            }
        })

onPageSelectedのタイミングでposition(その時のページ)が最初と最後の時ボタンをINVISIBLEにする

OnPageChangeListener メソッド

メソッド名 呼び出されるタイミング
onPageSelected 新しいページが選択され終わったとき
onPageScrollStateChanged スクロールの状態が変わった時(多分スクロールされ始めた時とスクロールを終えたとき「状態:スクローリング」「状態:停止」って感じで動く)
onPageScrolled ページがスクロールされている最中

onPageScrollStateChangedのとこだけあんまり自信がないので間違ってたら教えてください。

おわり

onPageSelectedしか使ってないけどなんとなくでOnPageChangeListener使いました。
kotlin好き。
今回フリー素材のイラストを利用させていただきました。(三日月アルペジオ)

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5