Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android center align the selected tab in tablayout

I am using android support design tablayout. Here's my code:

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content""
        app:tabGravity="center"
        app:tabMode="scrollable"
        />

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

My issue is the tabs always align left. However, I would like to center the selected tab (even at the beginning, the first(selected) tab should be centered). Is there a way to do this? Thanks.

like image 862
Shumin Gao Avatar asked Aug 18 '15 22:08

Shumin Gao


People also ask

How do you center a tab in a tab layout?

Option 1 — fill (default): Occupy the whole width of TabLayout and each tab has equal width. Option 2 — center: All tabs are centered within TabLayout and each tab has the same width as that of the widest tab. Option 1 — fixed: Display all tab at the same time and each tab has equal width which is based on the widest tab label.

What is tablayout in Android design support?

In Android TabLayout is a new element introduced in Design Support library. It provides horizontal layout to display tabs on the screen. We can display more screens in a single screen using tabs. We can quickly swipe between the tabs. TabLayout is basically view class required to be added into our layout (xml) for creating Sliding Tabs.

How to align the tab selection indicator in the tablayout?

Set the indicator gravity used to align the tab selection indicator in the TabLayout . You must set the indicator height via the custom indicator drawable's intrinsic height (preferred), via the tabIndicatorHeight attribute (deprecated), or via setSelectedTabIndicatorHeight (int) (deprecated).

How to display tabs in tablayout?

TabLayout provides a horizontal layout to display tabs. Population of the tabs to display is done through TabLayout.Tab instances. You create tabs via newTab ().


4 Answers

If your target API is 23 or above, let me share one more option for consideration along with the configuration of app:tabContentStart suggested by SynerFlow, which could let the end Tab be centered instead of swiped to the left-most edge during scrolling. However, I am still figuring out the approach for API before 23.

final int TAB_CONTENT_START = 96;   

tabLayout.setOnScrollChangeListener(new View.OnScrollChangeListener() {

    @Override
    public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

        final int maxAllowWidthOfTabBar = tabLayout.getMeasuredWidth() + TAB_CONTENT_START;
        if (scrollX > maxAllowWidthOfTabBar)
            tabLayout.setScrollX(maxAllowWidthOfTabBar);

    }
});
like image 142
garykwwong Avatar answered Nov 03 '22 11:11

garykwwong


I took a look into TabLayout and tabContentStart only sets padding for its first child -> SlidingTabStrip, so I set it manually on both sides:

public class CenteringTabLayout extends TabLayout {
    public CenteringTabLayout(Context context) {
        super(context);
    }

    public CenteringTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CenteringTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        View firstTab = ((ViewGroup)getChildAt(0)).getChildAt(0);
        View lastTab = ((ViewGroup)getChildAt(0)).getChildAt(((ViewGroup)getChildAt(0)).getChildCount()-1);
        ViewCompat.setPaddingRelative(getChildAt(0), (getWidth()/2) - (firstTab.getWidth()/2),0,(getWidth()/2) - (lastTab.getWidth()/2),0);
    }
}

TabLayout's first 0 index child is the SlidingTabStrip.

like image 23
Lubos Horacek Avatar answered Nov 03 '22 11:11

Lubos Horacek


Perhaps you are looking for an xml attribute called app:tabContentStart. This attribute allows you push the active tab to the left according to the value specified, which is set in "dp" (kind of like a margin-left thing). For example, try putting your code like this:

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        app:tabContentStart="96dp"/> <-- Or whatever value you want here.

It doesn't exactly center the tab, but it gives you a similar effect as the Google Play Store tabs.

like image 27
Adifyr Avatar answered Nov 03 '22 11:11

Adifyr


public class MyTabLayout extends TabLayout {

    public MyTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTabMode(MODE_SCROLLABLE);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (!changed) return;
        int totalTabsWidth = 0;
        for (int i = 0; i < getTabCount(); i++)
            totalTabsWidth += ((ViewGroup) getChildAt(0)).getChildAt(i).getWidth();
        int padding = (getWidth() - totalTabsWidth) / 2;
        if (padding < 0) padding = 0;
        getChildAt(0).setPaddingRelative(padding, 0, padding, 0);
    }
}
like image 24
IQ.feature Avatar answered Nov 03 '22 09:11

IQ.feature