TabLayout
,并且想要更改字体,你需要向上一个解决方案中添加一个新的循环,像这样: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);
}
}
}
}
TabLayout
的所有人。 - Mario VelascosetTypeFace
的第一个参数是 TypeFace
,如果你找不到 Font
类(在我的环境中似乎不存在),可以使用它。 - Vahid Amiri创建您自己的自定义样式,并将父样式作为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" />
parent="TextAppearance.Design.Tab"
。 - JavatarTextAppearance.Widget.TabWidget
时,偶尔会出现奇怪的异常。@Javatar的答案为我解决了这个问题。 - funct7com.google.android.material.tabs.TabLayout
,因此我的样式的父级是 Widget.MaterialComponents.TabLayout
,除此之外,相同的解决方案,非常好用,谢谢。 - ProjectDeltapraveen Sharma的回答很好。只是有一个小建议:
在需要TabLayout
的任何地方,你可以简单地使用自己的CustomTabLayout
而不是到处使用changeTabsFont()
。
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
是一个包含 TextView
(也可以选择性地包含 ImageView
)的 LinearLayout
。因此,你可以让代码更简单:
@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
的方法是向其添加自定义视图。这里有一个很好的示例。
addTab(Tab tab, int position, boolean setSelected)
而不是 addTab(Tab tab)
。 - Vicky Chijwani<?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"
/>
请确保将此处的 ID 保持不变,因为如果使用自定义 TextView,则 TabLayout 将检查此 ID。
然后从代码中填充此布局,并在该 TextView 上设置自定义 Typeface,并将此自定义视图添加到选项卡中。
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);
}
tabTextColor
和 tabSelectedTextColor
属性? - Alireza Noorali要在运行Android 4.1
(API级别16)及更高版本的设备上使用XML
功能中的字体支持,请使用Support Library 26+。
myfont.ttf
文件放入新创建的字体文件夹中在res/values/styles.xml
中添加:
<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
<item name="android:fontFamily">@font/myfont</item>
</style>
在布局文件中添加 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" />
请查看[XML中的字体]。(https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml)parent="TextAppearance.Design.Tab"
,否则@android:style/TextAppearance.Small
就可以了。 - DIRTY DAVE如果您正在使用
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" />
ViewGroup
中的字体。我选择这种方法是因为您不必关心TabLayout
的内部结构。我使用Calligraphy库来设置字体。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);
}
}
}
正如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);
}
}
}
}
必须重写 onLayout 方法,因为当你使用 setupWithViewPager 方法将 TabLayout 与 ViewPager 绑定时,必须使用 setText 方法或在 PagerAdapter 中设置选项卡文本,此时会调用父 ViewGroup(TabLayout)的 onLayout 方法,这是设置字体的位置。(更改 TextView 文本会导致其父级调用 onLayout 方法 - tabView 有两个子元素,一个是 ImageView,另一个是 TextView)
另一种解决方案:
首先,这些代码行:
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
}
在上面的解决方案中,应该写在两个循环之外。<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>
onLayout()
,在许多标签的嵌套 TabLayout
应用程序中使用嵌套的for
循环将导致卡顿。 - Amr BarakatonLayout()
会被多次调用(不太确定为什么),但是为了解决这个问题,我只在布尔值changed
为true
时设置字体。这样做可以防止多次设置字体。 - Robert如果要使用 23.2.0 版本的设计支持库中的 setupWithViewPager 方法,请将代码从 addTab(Tab tab) 改为 addTab(Tab tab, boolean setSelected)。
你可以使用这个,这对我很有效。
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);
}
}
}
}