23
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TabLayoutのTab毎に異なるIndicator色を設定したい

Last updated at Posted at 2015-07-08

2015/8/27追記

  • Android Support Library 23でTabLayout#setSelectedTabIndicatorColorが用意されました。

やりたいこと

tablayout_example.gif

  • Design Support LibraryのTabLayoutを使って
  • 各Tabのインジケーターの色を変えたかった
    • 例: Tab1のインジケータ: 赤
    • Tab2のインジケータ: 青

問題

TabLayoutのインジケータ色の設定方法

  • XML内でapp:tabIndicatorColorに設定してやればいいだけだが、これだけだと全タブのインジケータ色は一つになってしまう。

<android.support.design.widget.TabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorColor="@color/hoge_color" />

解決方法

  • Android Design Support Library 23で提供されたセッターを使えばおk
NewAndroidLibrary.java
mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                switch (tab.getPosition()) {
                    case 0:
                        mTabLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.blue));
                        break;
                    case 1:
                        mTabLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.red));
                        break;
                    case 2:
                        mTabLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.green));
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

ソースコード上の制限

  • Android Design Support LibraryのTabLayoutは、下記のようになっているので、一見自由にインジケータ色を設定出来そうだが、mTabStripはprivateなメンバ変数であり、getterもなさそうだった...~~
  • 上記の内容はAndroid Support Library 23で解決されました
TabLayout.class
public TabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
//----略-----
        this.mTabStrip = new TabLayout.SlidingTabStrip(context);        
     this.mTabStrip.setSelectedIndicatorColor(a.getColor(styleable.TabLayout_tabIndicatorColor, 0));
//----略-----

解決(Deprecated)

reflectionする(超むりやり)

  • Android Design Support Library 23系でIndicator Colorへのセッターが用意されたので、以下はdeprecatedです
deprecated.java
mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                if (tab.getPosition() == 0) {
                    changeTabIndicatorColor(getResources().getColor(R.color.transaction_out_color));
                } else if (tab.getPosition() == 1) {
                    changeTabIndicatorColor(getResources().getColor(R.color.transaction_in_color));
                } else if (tab.getPosition() == 2) {
                    changeTabIndicatorColor(getResources().getColor(R.color.transaction_ex_color));
                }

                viewPager.setCurrentItem(tab.getPosition(), false); // タブ内のページも切り替えないといけない。
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

private void changeTabIndicatorColor(int colorIdInHex) {
        try {
            Field field = TabLayout.class.getDeclaredField("mTabStrip");
            field.setAccessible(true);
            Object ob = field.get(mTabLayout);
            Class<?> c = Class.forName("android.support.design.widget.TabLayout$SlidingTabStrip");
            Method method = c.getDeclaredMethod("setSelectedIndicatorColor", int.class);
            method.setAccessible(true);
            method.invoke(ob, colorIdInHex);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
  • 強引....もっとスマートな方法があるはずです...
  • でも今のところ見つかってません(涙

参照

23
25
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
23
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?