woshidan's blog

そんなことよりコードにダイブ。

TabレイアウトでTabの内容の部分に任意のFragmentを入れる

面倒くさいからとりあえずメモがてらに置いてしまおう。

この記事この記事この記事を参考に頑張っていたのですが、最終的に下記の記事を参考に頑張ってました。

http://www.truiton.com/2015/06/android-tabs-example-fragments-viewpager/

コードはほとんど上記記事と同じなのでコードの構成について書きます。

内容

  • Layoutの構成について
    • TabHost, TabWidgetの場合
    • TabLayoutの場合
    • TabLayoutとViewPagerの関係
      • TabLayoutとViewPagerを使いつつスワイプで遷移させたくない場合

Layoutの構成について

2011年くらいからある TabHost/TabWidget クラスを使ったものと、さらに古くはTextViewなどを利用して自作したものと、最近出てきたサポートライブラリに含まれる TabLayoutViewPager を使ったものが出てきました。

せっかくなのでサポートライブラリの方を使ってできるなら楽をしたい、という感じで TabLayout の方を狙ってあれこれ。

TabHost, TabWidgetの場合

TabHost, TabWdiget の場合は、単純なものだと、TabHostの中にTabWidgetを、TabWidgetの下にTabの内容となるレイアウトのxmlを入れて、TabHostTabSpecTabHost#addTabメソッドで追加していたみたいです(ここなど)。

TabLayoutの場合

TabLayout で切り替えたい項目を出して、 ViewPager にセットするフラグメント等の項目に対応するViewを置きます。

TabLayout のタブ選択イベントのリスナにで ViewPager の現在ページを変える関数をセットして、

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
          @Override
          public void onTabSelected(TabLayout.Tab tab) {
              // Tabが選択されたタイミングでViewPagerを動かす
              viewPager.setCurrentItem(tab.getPosition());
          }

ViewPager のページチェンジリスナに Tab のページチェンジイベントをセットします。

// https://developer.android.com/intl/ja/reference/android/support/design/widget/TabLayout.TabLayoutOnPageChangeListener.html
// viewPagerのPageに同期してTabのPageChangeListenerが動くようにする
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));

こうするとタブの選択とスワイプによるフラグメントの変化が同期して動く、なじみのある感じの動きになります。

TabLayoutとViewPagerを使いつつスワイプで遷移させたくない場合

ひとまず、ViewPagerのタッチイベントを上書きしてあげればいいようです。

参考: http://saku-na63.hatenablog.com/entry/2013/11/16/160859

最後に、FragmentStatePagerAdapterFragmentPagerAdapter と比べてどう違うのという感じだけど、 内部の処理が異なっていて、切り替えたいページ数によって適するものが違うみたいです。