Изменение шрифта текста вкладки в Android design support TabLayout

Я пытаюсь работать над новым TabLayout из библиотеки дизайна android.

Я хочу изменить текст вкладки на шрифт. И я попытался найти некоторые стили, связанные с TabLayout,а закончилось этой.

пожалуйста, руководство, как я могу изменить в разделе шрифты.

15 ответов


создайте TextView из кода Java или XML, как это

<?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"
/>

убедитесь, что сохранить идентификатор, как это здесь, потому что TabLayout проверить этот идентификатор, если вы используете пользовательский textview

затем из кода надуть этот макет и установить пользовательский Typeface на этом textview и добавьте этот пользовательский вид на вкладку

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);
}

Если вы используете TabLayout и вы хотите изменить шрифт, который вы должны добавить новый цикл for к предыдущему решению, например:

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);
                }
        }
    }
} 

пожалуйста, обратитесь к изменить стиль шрифта на вкладках панели действий с помощью sherlock


отличный ответ от Правин Шарма. Просто небольшое дополнение: Вместо использования changeTabsFont() везде нужно TabLayout, вы можете просто использовать свой собственный 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);
            }
        }
    }

}

и еще одно. TabView это LinearLayout С TextView внутри (он также может дополнительно содержать ImageView). Таким образом, вы можете сделать код еще проще:

@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);
}

но я бы не рекомендовал этот путь. Если TabLayout реализация изменится, этот код может работать неправильно или даже крушение.

другой способ, чтобы настроить TabLayout добавить пользовательский вид к нему. Вот великий пример.


создайте свой собственный стиль и используйте родительский стиль как parent="@android:style/TextAppearance.Widget.TabWidget"

и в вашем макете вкладки используйте этот стиль как app:tabTextAppearance="@style/tab_text"

пример: Стиль:

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

пример: компонент компоновки вкладки:

<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" />

следующий метод изменит шрифт во всем ViewGroup рекурсивно. Я выбрал этот метод, потому что вам не нужно заботиться о внутренней структуре TabLayout. Я использую каллиграфия библиотека для установки шрифта.

void changeFontInViewGroup(ViewGroup viewGroup, String fontPath) {
    for (int i = 0; i < viewGroup.getChildCount(); i++) {
        View child = viewGroup.getChildAt(i);
        if (TextView.class.isAssignableFrom(child.getClass())) {
            CalligraphyUtils.applyFontToTextView(child.getContext(), (TextView) child, fontPath);
        } else if (ViewGroup.class.isAssignableFrom(child.getClass())) {
            changeFontInViewGroup((ViewGroup) viewGroup.getChildAt(i), fontPath);
        }
    }
}

для поддержки дизайна 23.2.0, используя setupWithViewPager, вам придется переместить код из addTab(tab tab) в addTab (tab tab, boolean setSelected).


Ну, я нашел его простым в 23.4.0 без использования цикла. Просто переопределите addTab (@nonnull Tab tab, boolean setSelected), как предложено @ ejw.

@Override
public void addTab(@NonNull Tab tab, boolean setSelected) {
    CoralBoldTextView coralTabView = (CoralBoldTextView) View.inflate(getContext(), R.layout.coral_tab_layout_view, null);
    coralTabView.setText(tab.getText());
    tab.setCustomView(coralTabView);

    super.addTab(tab, setSelected);
}

и вот XML

<?xml version="1.0" encoding="utf-8"?>
<id.co.coralshop.skyfish.ui.CoralBoldTextView
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/custom_text"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:ellipsize="end"
   android:gravity="center"
   android:singleLine="true"
   android:textColor="@color/graylove"
   android:textSize="@dimen/tab_text_size" />

надеюсь, что это может помочь :)


вы можете использовать это, это работает для меня.

 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) {
                AssetManager mgr = getActivity().getAssets();
                Typeface tf = Typeface.createFromAsset(mgr, "fonts/Roboto-Regular.ttf");//Font file in /assets
                ((TextView) tabViewChild).setTypeface(tf);
            }
        }
    }
}

As Андрей ответил, Вы можете изменить fontface путем расширения TabLayout класса. И как Penzzz сказал, Вы не можете сделать это addTab метод. Переопределить метода onlayout метод, как показано ниже:

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom){
    super.onLayout(changed, left, top, right, bottom);

    final ViewGroup tabStrip = (ViewGroup)getChildAt(0);
    final int tabCount = tabStrip.getChildCount();
    ViewGroup tabView;
    int tabChildCount;
    View tabViewChild;

    for(int i=0; i<tabCount; i++){
        tabView = (ViewGroup)tabStrip.getChildAt(i);
        tabChildCount = tabView.getChildCount();
        for(int j=0; j<tabChildCount; j++){
            tabViewChild = tabView.getChildAt(j);
            if(tabViewChild instanceof AppCompatTextView){
                if(fontFace == null){
                    fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
                }
                ((TextView) tabViewChild).setTypeface(fontFace, Typeface.BOLD);
            }
        }
    }
}

необходимо перезаписать метод onLayout, потому что, когда вы используете setupWithViewPager метод чтобы связать TabLayout с ViewPager, вы должны установить текст вкладок либо с помощью метода setText, либо в PagerAdapter после этого и когда это произошло, метод onLayout вызывается в родительской ViewGroup (TabLayout), и это место для установки fontface.(Изменение TextView text вызывает вызов метода onLayout его родителя-у tabView есть два ребенка, один-ImageView другой-TextView)


мой метод разрешения так же, как это, измените указанный текст вкладки,

 ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
 ViewGroup vgTab = (ViewGroup) vg.getChildAt(1);
 View tabViewChild = vgTab.getChildAt(1);
 if (tabViewChild instanceof TextView) {
      ((TextView) tabViewChild).setText(str);
 }

использовать поддержку шрифтов в XML функция на устройствах под управлением Android 4.1 (уровень API 16) и выше, используйте библиотеку поддержки 26+.

  1. щелкните правой кнопкой мыши папку res
  2. новый - > каталог ресурсов Android - > выберите шрифт - > Ok
  3. положить myfont.ttf файл во вновь созданной папке шрифта

On res/values/styles.xml добавить:

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

в файле макета добавить приложение: 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" />

пожалуйста см. раздел [шрифты в xml].(https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml)


мой 2p, Котлин с проверкой ссылки, применимый везде, поскольку он остановится, если что-то не так.

private fun setTabLayouFont(tabLayout: TabLayout) {
    val viewGroupTabLayout = tabLayout.getChildAt(0) as? ViewGroup?
    (0 until (viewGroupTabLayout?.childCount ?: return))
            .map { viewGroupTabLayout.getChildAt(it) as? ViewGroup? }
            .forEach { viewGroupTabItem ->
                (0 until (viewGroupTabItem?.childCount ?: return))
                        .mapNotNull { viewGroupTabItem.getChildAt(it) as? TextView }
                        .forEach { applyDefaultFontToTextView(it) }
            }
}

I think this is easier way.

<android.support.design.widget.TabLayout
   android:id="@+id/tabs"
   app:tabTextColor="@color/lightPrimary"
   app:tabSelectedTextColor="@color/white"
   style="@style/CustomTabLayout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"/>
<style name="CustomTabLayout" parent="Widget.Design.TabLayout">
   <item name="tabMaxWidth">20dp</item>
   <item name="tabMode">scrollable</item>
   <item name="tabIndicatorColor">?attr/colorAccent</item>
   <item name="tabIndicatorHeight">2dp</item>
   <item name="tabPaddingStart">12dp</item>
   <item name="tabPaddingEnd">12dp</item>
   <item name="tabBackground">?attr/selectableItemBackground</item>
   <item name="tabTextAppearance">@style/CustomTabTextAppearance</item>
   <item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>
<style name="CustomTabTextAppearance" parent="TextAppearance.Design.Tab">
   <item name="android:textSize">16sp</item>
   <item name="android:textStyle">bold</item>
   <item name="android:textColor">?android:textColorSecondary</item>
   <item name="textAllCaps">false</item>
</style>

расширение Котлина, которое работало для меня:

fun TabLayout.setFont(font: FontUtils.Fonts) {
    val vg = this.getChildAt(0) as ViewGroup
    for (i: Int in 0..vg.childCount) {
        val vgTab = vg.getChildAt(i) as ViewGroup?
        vgTab?.let {
            for (j: Int in 0..vgTab.childCount) {
                val tab = vgTab.getChildAt(j)
                if (tab is TextView) {
                    tab.typeface = FontUtils.getTypeFaceByFont(FontUtils.Fonts.BOLD, context)
                }
            }
        }
    }
}

изменить

if (tabViewChild instanceof TextView) {

на

if (tabViewChild instanceof AppCompatTextView) { 

чтобы заставить его работать с Android.поддержка.дизайн.штучка.TabLayout (по крайней мере, от com.андроид.поддержка:дизайн:23.2.0)