Change the font of tab text in android design support TabLayout

98,499

Solution 1

Create a TextView from Java Code or XML like this

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:textSize="15sp"
    android:textColor="@color/tabs_default_color"
    android:gravity="center"
    android:layout_height="match_parent"
/>

Make sure to keep the id as it is here because the TabLayout check for this ID if you use custom textview

Then from code inflate this layout and set the custom Typeface on that textview and add this custom view to the tab

for (int i = 0; i < tabLayout.getTabCount(); i++) {
     //noinspection ConstantConditions
     TextView tv = (TextView)LayoutInflater.from(this).inflate(R.layout.custom_tab,null)
     tv.setTypeface(Typeface);       
     tabLayout.getTabAt(i).setCustomView(tv);
}

Solution 2

If you are using TabLayout and you want to change the font you have to add a new for loop to the previous solution like this:

private void changeTabsFont() {
    ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
        int tabsCount = vg.getChildCount();
        for (int j = 0; j < tabsCount; j++) {
            ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
            int tabChildsCount = vgTab.getChildCount();
            for (int i = 0; i < tabChildsCount; i++) {
                View tabViewChild = vgTab.getChildAt(i);
                if (tabViewChild instanceof TextView) {
                    ((TextView) tabViewChild).setTypeface(Font.getInstance().getTypeFace(), Typeface.NORMAL);
                }
        }
    }
} 

Please refer to change font style in action bar tabs using sherlock

Solution 3

Create your own custom style and use parent style as parent="@android:style/TextAppearance.Widget.TabWidget"

And in your tab layout use this style as app:tabTextAppearance="@style/tab_text"

Example: Style:

<style name="tab_text" parent="@android:style/TextAppearance.Widget.TabWidget">
    <item name="android:fontFamily">@font/poppins_regular</item>
</style>

Example: Tab layout component:

<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:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:tabTextAppearance="@style/tab_text" />

Solution 4

Great answer from praveen Sharma. Just a small addition: Instead of using changeTabsFont() everywhere you need TabLayout, you can simply use your own CustomTabLayout.

import android.content.Context;
import android.graphics.Typeface;
import android.support.design.widget.TabLayout;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class CustomTabLayout extends TabLayout {
    private Typeface mTypeface;

    public CustomTabLayout(Context context) {
        super(context);
        init();
    }

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

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

    private void init() {
        mTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/Roboto-Regular.ttf");
    }

    @Override
    public void addTab(Tab tab) {
        super.addTab(tab);

        ViewGroup mainView = (ViewGroup) getChildAt(0);
        ViewGroup tabView = (ViewGroup) mainView.getChildAt(tab.getPosition());

        int tabChildCount = tabView.getChildCount();
        for (int i = 0; i < tabChildCount; i++) {
            View tabViewChild = tabView.getChildAt(i);
            if (tabViewChild instanceof TextView) {
                ((TextView) tabViewChild).setTypeface(mTypeface, Typeface.NORMAL);
            }
        }
    }

}

And one more thing. TabView is a LinearLayout with TextView inside (it can also optionally contain ImageView). So you can make the code even simpler:

@Override
public void addTab(Tab tab) {
    super.addTab(tab);

    ViewGroup mainView = (ViewGroup) getChildAt(0);
    ViewGroup tabView = (ViewGroup) mainView.getChildAt(tab.getPosition());
    View tabViewChild = tabView.getChildAt(1);
    ((TextView) tabViewChild).setTypeface(mTypeface, Typeface.NORMAL);
}

But I wouldn't recommend this way. If TabLayout implementation will change, this code can work improperly or even crash.

Another way to customise TabLayout is adding custom view to it. Here is the great example.

Solution 5

To use fonts support in XML feature on devices running Android 4.1 (API level 16) and higher, use the Support Library 26+.

  1. Right click res folder
  2. New -> Android resource directory-> select font -> Ok
  3. Put your myfont.ttf file in newly created font folder

On res/values/styles.xml add:

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/myfont</item>
</style>

On layout file add app:tabTextAppearance="@style/customfontstyle",

<android.support.design.widget.TabLayout
    android:id="@+id/tabs"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabGravity="fill"
    app:tabTextAppearance="@style/customfontstyle"
    app:tabMode="fixed" />

Please refer to [fonts in xml].(https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml)

Share:
98,499
Dory
Author by

Dory

Mobile Application Developer

Updated on August 10, 2021

Comments

  • Dory
    Dory almost 3 years

    I'm trying to work on the new TabLayout from the android design library.

    I want to change tab text to custom font. And,I tried to search some styling related to TabLayout,but ended up to this.

    Please guide how can I change the tab text fonts.

  • Dory
    Dory almost 9 years
    I am not using M preview. Is there any other way to do it.
  • Mario Velasco
    Mario Velasco over 8 years
    You don't need M preview, it is valid for everyone using TabLayout
  • Penzzz
    Penzzz about 8 years
    addTab wiil not invoke in case you set tabs like this: mViewPager.setAdapter(new YourPagerAdapter(getChildFragmentManager())); mTabLayout.setupWithViewPager(mViewPager);
  • Andrei Aulaska
    Andrei Aulaska about 8 years
    @Penzzz you are absolutely right. In this case you should move the code from addTab method to another. For example onMeasure.
  • Shirane85
    Shirane85 about 8 years
    but AppCompatTextView extends TextView, so why this would make a difference?
  • Amol Dale
    Amol Dale about 8 years
    @AndreiAulaska thnx You save my day . Your last Link save me.
  • brettbrdls
    brettbrdls about 8 years
    However, I'm encountering a NullPointerException on android.view.View android.support.design.widget.TabLayout.getChildAt(int), can you help me how to fix it? Can't find what am I missing on my code.
  • Mostafa Imran
    Mostafa Imran almost 8 years
    But how to set tabSelectedTextColor and tabTextColo?
  • Sayem
    Sayem over 7 years
    this does not work anymore i think in latest version. @ejw's answer is now working. need to add it in addTab(Tab tab, boolean setSelected)
  • Vahid Amiri
    Vahid Amiri over 7 years
    The first parameter of setTypeFace is a TypeFace, in case if you can't find the Font class (which doesn't appear to exist for me)
  • AA_PV
    AA_PV over 7 years
    @MostafaImran your version of android:textColor="@color/graylove" should have the state list selector for that with state_selected color specified
  • Vicky Chijwani
    Vicky Chijwani almost 7 years
    This works well. NOTE: as of support library 25.x, you need to override addTab(Tab tab, int position, boolean setSelected) instead of addTab(Tab tab).
  • rupps
    rupps over 6 years
    problem with this is, if you attach the layout to a Viewpager, you will lose the customized fonts.
  • Javatar
    Javatar over 6 years
    This is correct, I'm using parent="TextAppearance.Design.Tab" in my case.
  • Alireza Noorali
    Alireza Noorali over 6 years
    How can I set tabTextColor and tabSelectedTextColor property in this situation?
  • Alireza Noorali
    Alireza Noorali over 6 years
    I get the solution from praveen Sharma's answer
  • Amr Barakat
    Amr Barakat over 6 years
    This is a bad performance fix, onLayout() got called with every layout change like tab switching or even list scrolling below the tabs, with nested fors in a many tabs TabLayout app will be lagy.
  • Arash
    Arash over 6 years
    @Amr Barakat. According to this link: developer.android.com/reference/android/view/…, int, int, int, int), this is not true. I tested it too. I put a break point in onLayout method and it's get called when the tabs are being created not on tab switching or list scrolling.
  • Sulfkain
    Sulfkain about 6 years
    This works much better than first answers, and without black magic (hidden api), which could break something in the future
  • Tram Nguyen
    Tram Nguyen almost 6 years
    just work when use fontFamily, not work when use fontPath
  • Robert
    Robert over 5 years
    For me onLayout() does get called multiple times when tab switching (not sure why exactly), but to account for this I only set the fonts when the boolean changed is true. Doing that prevents setting the fonts multiple times.
  • Esmail Jamshidiasl
    Esmail Jamshidiasl almost 5 years
    it works on xamarin forms and xamarin android.thanks
  • careful7j
    careful7j over 4 years
    great solution, no code required, only xml attributes
  • funct7
    funct7 over 4 years
    I was getting weird exceptions erratically when using TextAppearance.Widget.TabWidget. @Javatar 's answer fixed it for me.
  • X.Y.
    X.Y. over 4 years
    Great answer! Should extend "TextAppearance.Design.Tab" though
  • shanraisshan
    shanraisshan over 4 years
    tabs.getTabAt(1)?.text is not changing the text dynamically, once set.
  • ProjectDelta
    ProjectDelta almost 3 years
    I'm using com.google.android.material.tabs.TabLayout so my style's parent is Widget.MaterialComponents.TabLayout, other than that same solution, works great, thanks.
  • DIRTY DAVE
    DIRTY DAVE almost 2 years
    Simple answer better than the others. Note: if you want the text in all caps use parent="TextAppearance.Design.Tab" otherwise @android:style/TextAppearance.Small works