ViewPagerを使ってフラグメントの切り替えをスワイプとボタンでできるようにする。(kotlinで書きます) OnPageChangeListener
を使います
※今回はViewPager実装済みとしてやっていくのでアダプターなどには触れません。まだ実装してないよという方はよろしければこちら参考に。
[kotlin] ViewPagerでフラグメントを切り替える
#ボタンを作成
レイアウトファイルにボタンを作る。
<?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ファイルにつける。
#リスナーをセット
上記で作成したボタンにリスナーをセットする
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
だけになっている。
上記のコードに以下を追加する。
/// 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好き。
今回フリー素材のイラストを利用させていただきました。(三日月アルペジオ)