[Android] ViewPagerを使ったページ切り替えでフリック完了後のイベントを取得する

ViewPagerによるページ切り替えのイベントを取得する

表題のとおりViewPagerを使ったページ切り替えの実装で、フリック完了後のイベントを取得する方法についてのメモです。要件としては「フリックでのページ切り替え後に音を鳴らす」といった時などに使う感じです。

ググってもピンポイントな情報が得られなかったので書き残しておきます。

OnPageChangeListenerを実装

ViewPagerを使ったページ切り替えのイベントを取得するには、ViewPagerのページが変わった時のリスナーであるViewPager.OnPageChangeListenerを実装します。

OnPageChangeListenerのメソッド

OnPageChangeListenerには、以下3つのメソッドが用意されています。

  • onPageScrollStateChanged(int state)
  • onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
  • onPageSelected(int position)

それぞれの役割は以下のような感じかと(違っていたらご指摘ください)。

  • onPageScrollStateChanged:スクロール状態が変化したときに呼び出される
  • onPageScrolled:ページスクロール中に呼び出される
  • onPageSelected:ページが切り替わった時に呼び出される
onPageSelected() を使って音を鳴らすとページ切り替えが引っかかる?

手始めにページが切り替わった時に呼び出されるメソッド onPageSelected() を試してみました。

viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
	@Override
	public void onPageSelected(int position) {
		// 音鳴らす
	}
});

確かにこれでページが切り替わった際のイベントを取得できたのですが、音を鳴らす時にページ切り替えが引っかかる(音再生時に一瞬固まりワンテンポ遅れてページが切り替わる)感じになってしまいました。

そもそも音鳴らしたいのはページ切り替えが完了したあとなので…これはちょっと違うかなと。

onPageScrollStateChanged() ならスクロールの状態を取得できる

続いて、スクロール状態が変化したときに呼び出されるメソッド onPageScrollStateChanged() を試してみました。

onPageScrollStateChanged() では、スクロールの状態を取得することができます。

  • SCROLL_STATE_IDLE(0)
  • SCROLL_STATE_DRAGGING(1)
  • SCROLL_STATE_SETTLING(2)

実際に動かしてみると、引数のstateはそれぞれ以下のタイミングで値が取得できました。

  • ViewPagerの位置が落ち着いた状態が0
  • ViewPagerがドラッグされていると1
  • ViewPagerが最終的な位置に落ち着く前が2

今回はフリック完了後に音を鳴らせたいので、Viewの位置が落ち着いたタイミングである SCROLL_STATE_IDLE かどうかで判定することにしました。

viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
	@Override
	public void onPageScrollStateChanged(int state) {
		if (ViewPager.SCROLL_STATE_IDLE == state) {
			// 音鳴らす
		}
	}
});

上記コードにて「フリックでのページ切り替え後に音を鳴らす」という要件が満たせました。

余談1

今回は使いませんでしたが、onPageScrolled()ではスクロールの座標が取得できるので「一定位置まで動かしたら何かする」ということが実現できそうです。

余談2

音の再生にはMediaPlayerクラスを使っているのですが、再生を行う際に若干の遅延が生じるとの情報もありました。SoundPoolというクラスもあるようですが、効果音鳴らすとかだったらこっちの方が良いのかな?

このあたりはいずれ詳しく調べてみたいと思います。

参考

ViewPager.OnPageChangeListener | Android Developers

未整理ブログ : ViewPagerで表示ページが変わったことを検知する方法

ViewPagerでページ番号を取得して何らかの処理を行う - ぷろぐらむおいしいよ

Android UI Cookbook for 4.0 ICS(Ice Cream Sandwich)アプリ開発術

  • わかりやすい解説ありがとうございます!参考になりましたー!