How to change indicator of tablayout to top from bottom?

19,036

Solution 1

Don't use scale = -1 and things like that.

From XML you can use app:tabIndicatorGravity="top"

From code you can use setSelectedTabIndicatorGravity(INDICATOR_GRAVITY_TOP)

Solution 2

It can be done by xml attribute, use android:scaleY="-1" in xml code. The view will flip vertically. Use the same method to correct the text and image used in tab title.

In xml file:

<android.support.design.widget.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:scaleY="-1"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

In Java code

tabLayout = (TabLayout) findViewById(R.id.tabLayout);

// Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Section 1"));
tabLayout.addTab(tabLayout.newTab().setText("Section 2"));
tabLayout.addTab(tabLayout.newTab().setText("Section 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

TextView tv1 = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(0)).getChildAt(1));
tv1.setScaleY(-1);
TextView tv2 = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(1)).getChildAt(1));
tv2.setScaleY(-1);
TextView tv3 = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(2)).getChildAt(1));
tv3.setScaleY(-1);

Sample screenshot

Solution 3

You can achieve this by rotating the TabLayout like this:

tabLayout.setRotationX(180);

Then you must rotate all of its TextView children back, or you can set the TabLayout a custom view, instead of recursively searching for a TextView:

TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(R.layout.layout_tab_view);

layout_tab_view.xml

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:rotationX="180"
        android:text="HOME"/>

I guess you loose some default functionality if you set a custom view, such as Fragment title naming from PagerAdapter and TextView disabled appearance, but you can bind that somehow together in another way.

enter image description here

Solution 4

Unfortunately you cannot do it by setting an attribute or setting it in code. TabLayout has a property mTabStrip of SlidingTabStrip (internal class), which is set as private final

private final SlidingTabStrip mTabStrip;

, so you cannot access it, by extending TabLayout.

So SlidingTabStrip (which extends LinearLayoyut)is a view which overrides draw method

@Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        // Thick colored underline below the current selection
        if (mIndicatorLeft >= 0 && mIndicatorRight > mIndicatorLeft) {
            canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,
                    mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
        }
    }

So you can see that it draws the rectangle with a top and bottom properties.

May be in future they will have a flag to change it.

Solution 5

You only need those lines

tabLayout.setRotationX(180);

    tabListed = ((LinearLayout)tabLayout.getChildAt(0));
    for(int position = 0;position<tabListed.getChildCount();position++) {
        LinearLayout item=((LinearLayout) tabListed.getChildAt(position));
        item.setBackground(getDrawable(R.drawable.square_tab));
        item.setRotationX(180);
    }

First tab rotation turn tab layout 180º then you will get all tabs and them turn it 180º. So they be good again.

enter image description here

Share:
19,036

Related videos on Youtube

Wuttipong Khemphetjetsada
Author by

Wuttipong Khemphetjetsada

Updated on September 15, 2022

Comments

  • Wuttipong Khemphetjetsada
    Wuttipong Khemphetjetsada over 1 year

    I want to change indicator of tablayout from bottom to top.

    my code

    activity_tab.xml

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
    
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
    
            app:tabIndicatorColor="#000000"
    
            app:tabMode="scrollable"
            />
    </android.support.design.widget.AppBarLayout>
    
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    

    I want this result.

    enter image description here

    how to do

    thx for ask me and sorry for bad english.

  • Shabbir Dhangot
    Shabbir Dhangot about 7 years
    What if I have five tabs with different sizes?
  • Nayan
    Nayan about 7 years
    @ShabbirDhangot - Use a linear layout instead. But there will not be any animation while changing the tabs.
  • Shabbir Dhangot
    Shabbir Dhangot about 7 years
    kartik agarval solution worked for me. you solution not working for uneven space of tabs.
  • Simon Ninon
    Simon Ninon over 5 years
    underrated, probably because it has been added recently to the standard library, but that's definitely the way to go, thanks for sharing!
  • Muhammed Arshad K
    Muhammed Arshad K over 5 years
    @Wilhelm Thanks :)
  • Sandesh Baliga
    Sandesh Baliga about 5 years
    As @Michael told in the answer below, app:tabIndicatorGravity="top" works smooth