ViewPager + TabLayoutで選択済みタブを再選択したときに処理を行う
追記(2017/2/14)
ちょっと今さらな感じはありますが、Support Library 24.0.0からTabLayout
に複数のリスナーが設定できるようになりましたので、そちらのやり方も追記しました。
TabLayoutで選択済みタブを再選択したときに処理を行いたい場合、TabLayout.OnTabSelectedListener
というインターフェースのonTabReselected
を実装して、TabLayoutに設定する必要があります。
Support Library 24.0.0より前のバージョンでのやりかた
ViewPagerとTabLayoutの連動について
通常、ViewPagerと連動させる場合はTabLayout.setupWithViewPager
を実行することになりますが、このメソッドの中でTabLayout.OnTabSelectedListener
もよしなに設定してくれるようです。
このとき設定されるリスナーは、TabLayoutの内部クラスとして定義されているTabLayout.ViewPagerOnTabSelectedListener
になります。
このリスナーは、onTabReselected
メソッドの実装が空なので、選択済みタブを再選択しても何も起きません。
そのため、何かしら処理を行いたい場合は独自に実装したリスナーをTabLayoutに設定する必要があります。
対応方法
独自に実装したリスナーを設定する場合、setupWithViewPagerでよしなに設定されている箇所を個別に対応していけばよいのですが、どうもSupportLibrary 23.4.0時点のTabLayoutに実装されているpublicメソッドでは、setupWithViewPagerで行っている処理をすべて代替することができないようです。
ソースを見たところ、今回問題になっているリスナーの設定はメソッドが用意されているので可能なのですが、他の処理で代替できない箇所があるため、かゆいところに手が届かない感じでした。
duplicatedになっているメソッドがsetupWithViewPagerで使われていたりもするので、基本的に連動させるときはsetupWithViewPagerを使うことが前提になっているようです。
そのため、実現するためには以下のどちらかで対応したほうがよさそうです。
1. TabLayoutには何も手を加えず、setupWithViewPagerを実行したあとに独自に実装したTabLayout.OnTabSelectedListenerを設定する。
メリット
- 用意されているAPIで対応できるため、事前の準備が必要ない。
デメリット
- setupWithViewPagerを実行した後に、リスナーを再度設定する必要がある。 ※リスナーは、最後に設定したものが利用されるので順序が逆ではダメ
- setupWithViewPager内でもリスナーが生成されているので、リスナーのインスタンス生成回数が1回余分に増える。
2. TabLayoutを継承して、setupWithViewPagerと同等の処理を個別に行うメソッドを実装する。
メリット
- 1と比べて余分なインスタンス生成が発生せず、柔軟にリスナーを切り替えることができるようになる。
デメリット
- 独自TabLayoutを使うときに意識する作法が増える。 ※実装方法によりますが、標準のsetupWithViewPagerを使わない等が挙げられると思います。
手軽なのは1ですね。リスナーのインスタンス生成が1回余分に発生するところがよくないですが、この処理を行うActivityが何度も生成・破棄されないという前提であれば、この方法でもありかなと思います。
この記事では1の方法で対応します。
実際の対応について
やることは書いてある通り、setupWithViewPagerを実行したあとに独自に実装したTabLayout.OnTabSelectedListener
を設定するだけなのですが、単純にこのインターフェースを実装したものをTabLayoutに設定するとViewPagerとの連動がうまく行われなくなってしまいます。
そこで、setupWithViewPagerの中で設定しているTabLayout.ViewPagerOnTabSelectedListener
を継承してリスナーを定義します。onTabReselected
メソッドは、元々は空の実装であるためオーバーライドしてもViewPagerとの連動に影響がありません。
あとは、このリスナーを設定してあげれば大丈夫です。
サンプルでは、ViewPagerOnTabSelectedListener
を継承した無名クラスを設定しています。
tabLayout.setupWithViewPager(viewPager);
TabLayout.OnTabSelectedListener onTabSelectedListener = new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
@Override
public void onTabReselected(TabLayout.Tab tab) {
// 選択済みタブが再選択されたときに行いたい処理を書く
}
};
tabLayout.setOnTabSelectedListener(onTabSelectedListener);
TabLayout.OnTabSelectedListener
に定義されているonTabUnselected
についても同じ要領で対応することができます。(あまり利用する場面が思い浮かびませんが。。。
サンプルをGitHubに上げています。
https://github.com/djyugg/Android-TabLayout-ReselectSample/tree/support-library-23.4.0
Support Library 24.0.0以降のやりかた
Support Library 24.0.0以降では、TabLayout.setOnTabSelectedListener
がdeprecatedとなり、TabLayout.addOnTabSelectedListener
が追加されました。
このメソッドを使うことによって、既に設定されてあるリスナーを上書きせずにリスナーを追加することができるようです。
よって、TabLayout.OnTabSelectedListener
を実装してTabLayout.addOnTabSelectedListener
に追加してあげれば、ViewPagerとの連動もそのままで処理を追加できます。
tabLayout.setupWithViewPager(mViewPager);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
Log.v("OnTabSelectedListener", "onTabUnselected SECTION " + tab.getTag());
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
Log.v("OnTabSelectedListener", "onTabReselected SECTION " + tab.getTag());
}
});
GitHubのサンプルも、こちらの内容で更新しました。
https://github.com/djyugg/Android-TabLayout-ReselectSample
Author And Source
この問題について(ViewPager + TabLayoutで選択済みタブを再選択したときに処理を行う), 我々は、より多くの情報をここで見つけました https://qiita.com/djyugg/items/a84f63cca3dcf53f04f8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .