I want to make the text of a selected tab bold. How can I do this either through xml or java code, whatever is easier.
13 Answers
I changed the answer suggested above a bit and it works great for me, no additional .xml files needed, hope it will help.
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
if (tab != null) {
TextView tabTextView = new TextView(this);
tab.setCustomView(tabTextView);
tabTextView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
tabTextView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
tabTextView.setText(tab.getText());
// First tab is the selected tab, so if i==0 then set BOLD typeface
if (i == 0) {
tabTextView.setTypeface(null, Typeface.BOLD);
}
}
}
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
TextView text = (TextView) tab.getCustomView();
text.setTypeface(null, Typeface.BOLD);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
TextView text = (TextView) tab.getCustomView();
text.setTypeface(null, Typeface.NORMAL);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});

- 474
- 5
- 13
-
```setOnTabSelectedListener``` is deprecated. Use ```addOnTabSelectedListener``` instead. – Ivan Mar 13 '20 at 21:56
-
`.setTypeFace(null, .. )` will remove the initialised font. Use `Typeface typeface = ResourcesCompat.getFont(this, R.font.your_font);` if you want to use a specific font. – Sven van Zoelen Sep 29 '20 at 13:45
If you use default TabLayout (not customView), you can get TextView of tab by using getChildAt() method.
.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
LinearLayout tabLayout = (LinearLayout)((ViewGroup) mMainTabs.getChildAt(0)).getChildAt(tab.getPosition());
TextView tabTextView = (TextView) tabLayout.getChildAt(1);
tabTextView.setTypeface(tabTextView.getTypeface(), Typeface.BOLD);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
LinearLayout tabLayout = (LinearLayout)((ViewGroup) mMainTabs.getChildAt(0)).getChildAt(tab.getPosition());
TextView tabTextView = (TextView) tabLayout.getChildAt(1);
tabTextView.setTypeface(null, Typeface.NORMAL);
}
@Override
public void onTabReselected(TabLayout.Tab tab) { }
});

- 2,472
- 2
- 18
- 19

- 2,168
- 20
- 22
-
3this sets the typeface to bold. but doesn't return it to NORMAL typeface on deselected?? – filthy_wizard Apr 04 '17 at 11:06
-
4This solution will work only if you replace "tabTextView.getTypeface()" with null when setting to NORMAL. – Zoran P Aug 20 '18 at 10:37
-
1@Zoran, your comment worked. How to ensure the first/default selected tab is bolden when the ViewPager is created? – saintjab Aug 21 '18 at 09:57
-
1
-
2
-
-
`.setTypeFace(null, .. )` will remove the initialised font. Use `Typeface typeface = ResourcesCompat.getFont(this, R.font.your_font);` if you want to use a specific font. – Sven van Zoelen Sep 29 '20 at 13:45
I know this is an old question, but I came up with a nicer solution:
I created this OnTabSelectedListener
class OnTabSelectedBoldListener : TabLayout.OnTabSelectedListener {
override fun onTabReselected(tab: TabLayout.Tab) {}
override fun onTabUnselected(tab: TabLayout.Tab) {
val views = arrayListOf<View>()
tab.view.findViewsWithText(views, tab.text, View.FIND_VIEWS_WITH_TEXT)
views.forEach { view ->
if (view is TextView) {
TextViewCompat.setTextAppearance(view, R.style.TabTextAppearance)
}
}
}
override fun onTabSelected(tab: TabLayout.Tab) {
val views = arrayListOf<View>()
tab.view.findViewsWithText(views, tab.text, View.FIND_VIEWS_WITH_TEXT)
views.forEach { view ->
if (view is TextView) {
TextViewCompat.setTextAppearance(view, R.style.TabTextAppearance_Selected)
}
}
}
}

- 71
- 1
- 4
There is a way to add bold programmatically by using a Tab CustomView, loading a TextView into that CustomView and applying styling on the TextView:
private TabLayout mTabLayout;
protected void onCreate(Bundle savedInstanceState) {
...
mTabLayout = (TabLayout) findViewById(R.id.tablayout);
mTabLayout.setOnTabSelectedListener(new OnTabSelectedListener());
int tabCount = mTabLayout.getTabCount();
for (int i = 0; i < tabCount; i++) {
TabLayout.Tab tab = mTabLayout.getTabAt(i);
if (tab != null) {
TextView tabTextView =
(TextView) LayoutInflater.from(this).inflate(R.layout.tab_item, mTabLayout, false);
tabTextView.setText(tab.getText());
// First tab is the selected tab, so if i==0 then set Tabs_Selected style
tabTextView.setTextAppearance(getAppContext(), i == 0 ? R.style.TextAppearance_Tabs_Selected
: R.style.TextAppearance_Tabs);
tab.setCustomView(tabTextView);
}
}
}
class OnTabSelectedListener implements TabLayout.OnTabSelectedListener {
public void onTabSelected(TabLayout.Tab selectedTab) {
int tabCount = mTabLayout.getTabCount();
for (int i = 0; i < tabCount; i++) {
TabLayout.Tab tab = mTabLayout.getTabAt(i);
View tabView = tab != null ? tab.getCustomView() : null;
if (tabView instanceof TextView) {
((TextView) tabView).setTextAppearance(getAppContext(), selectedTab.equals(tab)
? R.style.TextAppearance_Tabs_Selected
: R.style.TextAppearance_Tabs);
}
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
And here is the entries in styles.xml:
<style name="TextAppearance.Tabs" parent="TextAppearance.Design.Tab">
<item name="android:textSize">12sp</item>
<item name="android:textColor">@android:color/white</item>
</style>
<style name="TextAppearance.Tabs.Selected">
<item name="android:textStyle">bold</item>
</style>
And here is the layout tab_item:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tab_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Tab 1" />

- 1,197
- 11
- 14
This is a Kotlin code for this solution
for (i in 0..tabLayout.tabCount){
val tab:TabLayout.Tab? = tabLayout.getTabAt(i)
if (tab != null){
val tabTextView:TextView = TextView(this)
tab.customView = tabTextView
tabTextView.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
tabTextView.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
tabTextView.text = tab.text
if (i == 0){
// This set the font style of the first tab
tabTextView.setTypeface(null,BOLD)
}
if (i == 1){
// This set the font style of the first tab
tabTextView.setTypeface(null,NORMAL)
}
}
}
tabLayout!!.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
viewPager.currentItem = tab!!.position
val text:TextView = tab.customView as TextView
text.setTypeface(null,BOLD)
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
val text:TextView = tab?.customView as TextView
text.setTypeface(null,NORMAL)
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})

- 31
- 4
In my case, setTypeface
doesn't work right after tab init so I need to use post
method to wait TextView
laid out then setTypeface
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabReselected(tab: TabLayout.Tab?) {
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
tab?.let {
setStyleForTab(it, Typeface.NORMAL)
}
}
override fun onTabSelected(tab: TabLayout.Tab?) {
tab?.let {
setStyleForTab(it, Typeface.BOLD)
}
}
fun setStyleForTab(tab: TabLayout.Tab, style: Int) {
tab.view.children.find { it is TextView }?.let { tv ->
(tv as TextView).post {
tv.setTypeface(null, style)
}
}
}
})

- 57,942
- 23
- 262
- 279
I applied hoi's answer which is written above for default TabLayout with no custom view. It worked the best for me. But what I actually needed was to change the font family of the text inside the TabItem to a bolder one when a tab was selected. So following hoi's solution, I changed the code a bit to work for me. I am leaving this answer just in case if someone is trying to achieve something similar:
private fun addOnTabSelectedListener() {
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabReselected(tab: TabLayout.Tab?) {
return
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
tab?.position?.let {
changeSelectedTabItemFontFamily(it, R.font.quicksand_medium)
}
}
override fun onTabSelected(tab: TabLayout.Tab?) {
tab?.position?.let {
changeSelectedTabItemFontFamily(it, R.font.quicksand_bold)
}
}
})
}
private fun changeSelectedTabItemFontFamily(tabPosition: Int, @FontRes fontFamilyRes: Int) {
val linearLayout = (this.tabLayout.getChildAt(0) as ViewGroup).getChildAt(tabPosition) as LinearLayout
val tabTextView = linearLayout.getChildAt(1) as TextView
val typeface = ResourcesCompat.getFont(context, fontFamilyRes)
tabTextView.typeface = typeface
}

- 86
- 1
- 7
For me problem with above solutions was that reset to Typeface.NORMAL with
SetTypeface(null, Typeface.NORMAL);
wouldn't reset my typeface on default typeface for my tabs. So I had to save default typeface before it was changed in order to reset Typeface to defaultTypeface once when tab is deselected.
private TabLayout _tabLayout;
public override void OnViewCreated(View view, Bundle savedInstanceState)
{
_tabLayout = view.FindViewById<TabLayout>(Resource.Id.my_tab_layout);
_tabLayout.TabSelected += TabLayout_TabSelected;
_tabLayout.TabUnselected += TabLayout_TabUnselected;
}
private void TabLayout_TabSelected(object sender, TabLayout.TabSelectedEventArgs e)
{
SetTabTypeface(e.Tab, true);
}
private void TabLayout_TabUnselected(object sender, TabLayout.TabUnselectedEventArgs e)
{
SetTabTypeface(e.Tab, false);
}
Typeface _defaultTypeface;
private void SetTabTypeface(TabLayout.Tab tab, bool isSelected)
{
LinearLayout tabLinLayout = (LinearLayout)((ViewGroup)_tabLayout.GetChildAt(0)).GetChildAt(tab.Position);
TextView tabTextView = (TextView)tabLinLayout.GetChildAt(1);
if (_defaultTypeface == null)
_defaultTypeface = tabTextView.Typeface;
if (isSelected)
tabTextView.SetTypeface(tabTextView.Typeface, TypefaceStyle.Bold);
else
tabTextView.SetTypeface(_defaultTypeface, TypefaceStyle.Normal);
}

- 281
- 4
- 16
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_active));
if (tab.getPosition()==0){
tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.booking_active));
}
if(tab.getPosition()==1){
tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_active));
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
if (tab.getPosition()==0){
tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.booking_deacive));
}
if(tab.getPosition()==1){
tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_deactive));
}
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
if (tab.getPosition()==0){
tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.booking_active));
}
if(tab.getPosition()==1){
tab.getCustomView().setBackgroundDrawable(getResources().getDrawable(R.mipmap.account_active));
}
}
});
setupTabIcons();

- 37
- 2
Hello Friends Try This
first add this method
private void updateCounter() {
try {
for (int i = 0; i < tabLayout.getTabCount(); i++) {
updateTab(tabLayout.getTabAt(i));
}
} catch (Exception e) {
e.printStackTrace();
}
}
second add this Method
private void updateTab(TabLayout.Tab tab) {
Method method;
try {
method = TabLayout.Tab.class.getDeclaredMethod("getCustomView");
method.setAccessible(true);
View tabView = (View) method.invoke(tab, new Object[0]);
TextView tv_title = null;
if (tabView != null) {
tv_title = tabView.findViewById(R.id.tv_title);
}
switch (tab.getPosition()) {
case 0:
if (tv_title != null) {
tv_title.setText(tabTitle[0]);
if(viewPager.getCurrentItem() == 0){
tv_title.setTypeface(CustomerApplication.getInstance().getMontserratBold());
}else{
tv_title.setTypeface(CustomerApplication.getInstance().getMontserratMedium());
}
}
break;
case 1:
if (tv_title != null) {
tv_title.setText(tabTitle[1]);
if(viewPager.getCurrentItem() == 1){
tv_title.setTypeface(CustomerApplication.getInstance().getMontserratBold());
}else{
tv_title.setTypeface(CustomerApplication.getInstance().getMontserratMedium());
}
}
break;
}
tab.setCustomView(tabView);
} catch (Exception e) {
e.printStackTrace();
}
}
last call view pager change listener
private final ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
updateCounter();
}
@Override
public void onPageScrollStateChanged(int state) {
}
};

- 129
- 1
- 5
This works in JAVA
tabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
initTabSelection(tab);
for(int index = 0; index < ((ViewGroup) tab.view).getChildCount(); index++) {
View nextChild = ((ViewGroup) tab.view).getChildAt(index);
if (nextChild instanceof TextView) {
TextView v = (TextView) nextChild;
v.setTypeface(null, Typeface.BOLD);
}
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
for(int index = 0; index < ((ViewGroup) tab.view).getChildCount(); index++) {
View nextChild = ((ViewGroup) tab.view).getChildAt(index);
if (nextChild instanceof TextView) {
TextView v = (TextView) nextChild;
v.setTypeface(null, Typeface.NORMAL);
}
}
}
@Override
public void onTabReselected(TabLayout.Tab tab) { }
});

- 1,839
- 2
- 19
- 42
You can use this on your tablayout
app:tabSelectedTextAppearance="@style/TabSelected"
the style can be like:
<style name="TabSelected">
<item name="textAllCaps">false</item>
<item name="fontFamily">Whatever bold font you want to use</item>
</style>

- 11
- 2
-
Property not available for com.google.android.material.tabs.TabLayout, IDK where you get this! – Kishan Solanki Aug 09 '23 at 16:20
-
-
In addition to previous answers, bear in mind that when modifying the style of the text in the onTabUnselected you may have to recalculate the width of the view if it was set on WRAP_CONTENT
@Override
public void onTabSelected(TabLayout.Tab tab) {
TextView text = (TextView) tab.getCustomView();
text.setTypeface(null, Typeface.BOLD);
text.getCustomView().measure(WRAP_CONTENT, WRAP_CONTENT)
text.getCustomView().layoutParams.height = measuredHeight
text.getCustomView().layoutParams.width = measuredWidth
}

- 181
- 2
- 10