在android设计支持TabLayout中更改选项卡文本的字体

Dor*_*ory 96 fonts android android-fonts android-design-library android-tablayout

我正在尝试TabLayout从android设计库中处理新的东西.

我想将标签文本更改为自定义字体.并且,我试图搜索一些与之相关的样式TabLayout,但最终还是达到了这个目的.

请指导我如何更改标签文本字体.

Pra*_*rma 159

如果您正在使用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);
                }
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

请参阅使用sherlock在操作栏选项卡中更改字体样式


Mil*_*ada 85

创建自己的自定义样式并使用父样式 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>
Run Code Online (Sandbox Code Playgroud)

示例:选项卡布局组件:

<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" />
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的,我在我的情况下使用`parent ="TextAppearance.Design.Tab". (7认同)
  • 这应该是正确的方法;) (3认同)
  • 这比第一个答案要好得多,而且没有黑魔法(隐藏的 api),这可能会在未来破坏某些东西 (2认同)
  • 仅在使用fontFamily时有效,而在使用fontPath时则无效 (2认同)
  • 使用“TextAppearance.Widget.TabWidget”时,我经常遇到奇怪的异常。@Javatar 的回答为我解决了这个问题。 (2认同)
  • 我正在使用“com.google.android.material.tabs.TabLayout”,所以我的样式的父级是“Widget.MaterialComponents.TabLayout”,除了相同的解决方案之外,效果很好,谢谢。 (2认同)

And*_*ska 46

来自praveen Sharma的精彩回答.只是一个小小的补充:你可以简单地使用你自己的,而不是使用changeTabsFont()你需要的任何地方.TabLayoutCustomTabLayout

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

}
Run Code Online (Sandbox Code Playgroud)

还有一件事. 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);
}
Run Code Online (Sandbox Code Playgroud)

但我不建议这样做.如果TabLayout实现将发生变化,则此代码可能无法正常工作甚至崩溃.

另一种自定义方法TabLayout是向其添加自定义视图.这是一个很好的例子.

  • 这很好用.注意:从支持库25.x开始,您需要覆盖`addTab(Tab tab,int position,boolean setSelected)`而不是`addTab(Tab tab)`. (3认同)
  • @Penzzz你是绝对正确的.在这种情况下,您应该将代码从addTab方法移动到另一个方法.例如onMeasure. (2认同)

Far*_*ahi 32

像这样从Java代码或XML创建TextView

<?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"
/>
Run Code Online (Sandbox Code Playgroud)

请确保将ID保留在此处,因为如果您使用自定义textview,TabLayout会检查此ID

然后从代码中扩充此布局并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);
}
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,如何设置`tabTextColor`和`tabSelectedTextColor`属性? (2认同)

Egi*_*gis 16

以下方法将以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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Nis*_*arg 14

如果您正在使用

com.google.android.material:material:1.2.0(最新版本)

<style name="MyCustomTabTextAppearance" parent="TextAppearance.Design.Tab">
        <item name="fontFamily">Your Font</item>
        <item name="android:fontFamily">Your Font</item>
        <item name="textAllCaps">false</item>
    </style>

<com.google.android.material.tabs.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabBackground="@color/colorPrimary"
        app:tabGravity="fill"
        app:tabIndicatorColor="@color/white"
        app:tabMode="fixed"
        app:tabTextAppearance="@style/MyCustomTabTextAppearance"
        app:tabTextColor="@android:color/white" />
Run Code Online (Sandbox Code Playgroud)


Tho*_*V J 11

要在XML运行Android 4.1(API级别16)及更高版本的设备上使用字体支持功能,请使用支持库26+。

  1. 右键单击res文件夹
  2. 新建-> Android资源目录->选择字体->确定
  3. myfont.ttf文件放在新创建的字体文件夹中

res/values/styles.xml添加:

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/myfont</item>
</style>
Run Code Online (Sandbox Code Playgroud)

在布局文件上添加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" />
Run Code Online (Sandbox Code Playgroud)

请参考[xml中的字体]。(https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml


小智 10

对于设计支持23.2.0,使用setupWithViewPager,您必须将代码从addTab(Tab选项卡)移动到addTab(Tab选项卡,布尔setSelected).


els*_*nov 7

好吧,我在23.4.0中发现它很简单而没有使用循环.按照@ejw的建议覆盖addTab(@NonNull Tab选项卡,布尔setSelected).

@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);
}
Run Code Online (Sandbox Code Playgroud)

这是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" />
Run Code Online (Sandbox Code Playgroud)

希望它可以帮助:)


Ara*_*ash 7

正如Andrei回答的那样,您可以通过扩展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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

必须覆盖onLayout方法,因为当您使用setupWithViewPager方法将TabLayout与ViewPager绑定时,您必须使用setText方法或在PagerAdapter之后设置标签文本,并且当发生这种情况时,在父ViewGroup上调用onLayout方法( TabLayout),这是设置字体的地方.(更改TextView文本导致调用它的父项的onLayout方法 - 一个tabView有两个孩子,一个是ImageView,另一个是TextView)

另一种方案:

首先,这些代码行:

    if(fontFace == null){
        fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
    }
Run Code Online (Sandbox Code Playgroud)

在上面的解决方案中,应该写在两个循环之外.

API> = 16的更好解决方案是使用android:fontFamily:

创建名为font 的Android资源目录,并将所需的字体复制到该目录.

然后使用这些样式:

<style name="tabLayoutTitles">
    <item name="android:textColor">@color/white</item>
    <item name="android:textSize">@dimen/appFirstFontSize</item>
    <item name="android:fontFamily">@font/vazir_bold</item>
</style>

<style name="defaultTabLayout">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">@dimen/defaultTabLayoutHeight</item>
    <item name="android:gravity">right</item>
    <item name="tabTextAppearance">@style/tabLayoutTitles</item>
    <item name="tabSelectedTextColor">@color/white</item>
    <item name="tabIndicatorColor">@color/white</item>
    <item name="tabIndicatorHeight">@dimen/accomTabIndicatorHeight</item>
    <item name="tabMode">fixed</item>
    <item name="tabGravity">fill</item>
    <item name="tabBackground">@drawable/rectangle_white_ripple</item>
    <item name="android:background">@color/colorPrimary</item>
</style>
Run Code Online (Sandbox Code Playgroud)

  • @Amr Barakat。根据以下链接:https://developer.android.com/reference/android/view/View.html#onLayout(boolean,int,int,int,int),这是不正确的。我也测试过 我在** onLayout **方法中设置了一个断点,并且在创建选项卡时调用该断点,而不是在选项卡切换或列表滚动时调用。 (2认同)

pav*_*vel 7

你可以使用它,它适合我.

 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)