Android - 如何更改底部导航栏文本的字体系列

时间:2017-08-10 05:11:20

标签: android android-layout fonts typeface

我在Android页面中创建了一个底栏导航。但现在我想在底部导航文本中应用自定义字体系列。

这是.xml文件中的底部导航代码:

<android.support.design.widget.BottomNavigationView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/bottomNavView_Bar"
            android:background="@drawable/white_grey_border_top"
            app:menu="@menu/bottom_navigation_menu">
</android.support.design.widget.BottomNavigationView>

此外,bottom_navigation_menu.xml中的代码:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      >

    <item
        android:id="@+id/ic_newsfeed"
        android:icon="@drawable/ic_menu_camera"
        android:title="NEWSFEED"
        />

        <item
            android:id="@+id/ic_explorer"
            android:icon="@drawable/ic_home_black_24dp"
            android:title="EXPLORER"
            />
        <item
            android:id="@+id/ic_notify"
            android:icon="@drawable/ic_notifications_black_24dp"
            android:title="NOTIFY"
            />
        <item
            android:id="@+id/ic_more"
            android:icon="@drawable/ic_dashboard_black_24dp"
            android:title="MORE"
            />

</menu>

帮助将不胜感激。

提前致谢!

12 个答案:

答案 0 :(得分:61)

在res / font /文件夹中添加字体文件以将字体捆绑为资源

然后

您可以使用样式资源更改它。 在styles.xml中:

<style name="Widget.BottomNavigationView" 
    parent="Widget.Design.BottomNavigationView">
    <item name="fontFamily">@font/your_font</item>
</style>

然后将其作为主题应用于您的视图中:

<android.support.design.widget.BottomNavigationView
    ...
    android:theme="@style/Widget.BottomNavigationView"
/>

刚刚查看我的应用,它运行正常。

参考: https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html#fonts-in-code

答案 1 :(得分:8)

在您的布局中:

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:itemTextAppearanceActive="@style/BottomNavigationViewTextStyle"
    app:itemTextAppearanceInactive="@style/BottomNavigationViewTextStyle"
    ... />

在您的styles.xml中:

<style name="BottomNavigationViewTextStyle">
    ...
    <item name="android:fontFamily">@font/whatever_font</item>
    ...
</style>

答案 2 :(得分:5)

这可以通过覆盖 BottomNavigationView 类的 onLayout 方法然后使用扩展标记来完成。此方法还显示所有菜单标题并禁用移位。

public final class ExtendedBottomNavigationView extends BottomNavigationView{
    private final Context context;
    private Typeface fontFace = null;

    public ExtendedBottomNavigationView(Context context, AttributeSet attrs){
        super(context, attrs);
        this.context = context;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom){
        super.onLayout(changed, left, top, right, bottom);
        final ViewGroup bottomMenu = (ViewGroup)getChildAt(0);
        final int bottomMenuChildCount = bottomMenu.getChildCount();
        BottomNavigationItemView item;
        View itemTitle;
        Field shiftingMode;

        if(fontFace == null){
            fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.VazirBold));
        }
        try {
            //if you want to disable shiftingMode:
            //shiftingMode is a private member variable so you have to get access to it like this:
            shiftingMode = bottomMenu.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(bottomMenu, false);
            shiftingMode.setAccessible(false);
        } catch (NoSuchFieldException e){
            e.printStackTrace();
        } catch (IllegalAccessException e){e.printStackTrace();}

        for(int i=0; i<bottomMenuChildCount; i++){
            item = (BottomNavigationItemView)bottomMenu.getChildAt(i);
            //this shows all titles of items
            item.setChecked(true);
            //every BottomNavigationItemView has two children, first is an itemIcon and second is an itemTitle
            itemTitle = item.getChildAt(1);
            //every itemTitle has two children, first is a smallLabel and second is a largeLabel. these two are type of AppCompatTextView
            ((TextView)((BaselineLayout) itemTitle).getChildAt(0)).setTypeface(fontFace, Typeface.BOLD);
            ((TextView)((BaselineLayout) itemTitle).getChildAt(1)).setTypeface(fontFace, Typeface.BOLD);
        }
    }
}

然后像这样使用它:

<your.package.name.ExtendedBottomNavigationView android:id="@id/bottomMenu" style="@style/bottomMenu"/>

答案 3 :(得分:2)

对于每个https://material.io/develop/android/components/bottom-navigation-view/,只需为TextAppearance.MaterialComponents.Caption样式设置fontFamily项即可。 com.google.android.material.bottomnavigation.BottomNavigationView默认情况下会使用它。

只知道其他依赖于TextAppearance.MaterialComponents.Caption的组件也发生了变化,但这可能是理想的。

<style name="TextAppearance.MaterialComponents.Caption" parent="AppMaterialComponentsTheme">
        <item name="fontFamily">@font/example</item>
</style>

答案 4 :(得分:2)

对于Kotlin Lover

为自定义资产字体创建扩展类

    /**
      * Method for Bottom Navigation Font Family
      *@param view
      *
      * */
private fun navigationTextFont(view: View) {
    if (view is ViewGroup) {
        for (i in 0 until view.childCount) {
            val child = view.getChildAt(i)
            navigationTextFont(child)
        }
    } else if (view is TextView) {
        view.typeface = Typeface.createFromAsset(this.assets, "fonts/roboto_bold.ttf")
    }
}

现在叫这个扩展名

   navigationTextFont(yourNavigationViewId)

祝你好运

答案 5 :(得分:1)

自定义BottomNavigationView的Kotlin代码以设置自定义字体:

1。将字体保留到android studio项目的资产目录中。在这里,我使用了我的字体“ SolaimanLipi_20-04-07.ttf”

2。复制以下kotlin代码并将其粘贴到您的android studio项目中。

class FontBottomNavigationView : BottomNavigationView {


constructor(context: Context) : super(context) {

}

constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {

}

constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {

}

private var fontFace: Typeface? = null

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
    super.onLayout(changed, left, top, right, bottom)

    val bottomMenu = getChildAt(0) as ViewGroup
    val bottomMenuChildCount: Int = bottomMenu.childCount
    var item: BottomNavigationItemView? = null
    var itemTitle: View? = null
    var shiftingMode: Field? = null

    if (fontFace == null){
        fontFace = Typeface.createFromAsset(context.assets, "SolaimanLipi_20-04-07.ttf") // font from assets directory
    }

    try {
        shiftingMode = bottomMenu.javaClass.getDeclaredField("mShiftingMode")
        shiftingMode.isAccessible = true
        shiftingMode.setBoolean(bottomMenu, false)
        shiftingMode.isAccessible = false
    } catch (e: Exception){
        e.printStackTrace()
    }

    for (i in 0..bottomMenuChildCount){
        try {
            item = bottomMenu.getChildAt(i) as BottomNavigationItemView
            itemTitle = item.getChildAt(1)
            ((itemTitle as BaselineLayout).getChildAt(0) as AppCompatTextView).typeface = fontFace
            ((itemTitle as BaselineLayout).getChildAt(1) as AppCompatTextView).typeface = fontFace
        } catch (e: Exception){
            e.printStackTrace()
        }

    }

}}

3。在xml文件上使用,如下所示:

<com.example.projectname.FontBottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:menu="@menu/bottom_nav_menu" />

@Arash答案有所帮助:

答案 6 :(得分:1)

科林语:

1:使用自定义名称创建文件,例如:BottomNavigationViewExtension.kt

2:将代码放在下面:

import android.graphics.Typeface
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.google.android.material.bottomnavigation.BottomNavigationView

fun BottomNavigationView.changeNavTypeface(typeface: Typeface) {
    val view: View = this
    checker(view, typeface)

}
private fun checker(view: View, typeface: Typeface) {
    if (view is ViewGroup) {
        for (i in 0 until view.childCount) {
            val child = view.getChildAt(i)
            checker(child, typeface)
        }
    } else if (view is TextView) {
        view.typeface = typeface
    }
}

3:用法:

navView.changeNavTypeface(
    Typeface.createFromAsset(
        assets,
        "fonts/IRANSansMobile.ttf"
    )
)

答案 7 :(得分:0)

如果要在选择时动态更改文本选择,则可以执行bottomNav.itemTextAppearanceActive = R.style.yourstyle

答案 8 :(得分:0)

public void setNavigationTypeface() {
        final Typeface avenirHeavy = Typeface.createFromAsset(this.getAssets(), "font2/Avenir-Heavy.ttf"); //replace it with your own font
        ViewGroup navigationGroup = (ViewGroup) bottomNavView.getChildAt(0);
        for (int i = 0; i < navigationGroup.getChildCount(); i++) {
            ViewGroup navUnit = (ViewGroup) navigationGroup.getChildAt(i);
            for (int j = 0; j < navUnit.getChildCount(); j++) {
                View navUnitChild = navUnit.getChildAt(j);
                if (navUnitChild instanceof BaselineLayout) {
                    BaselineLayout baselineLayout = (BaselineLayout) navUnitChild;
                    for (int k = 0; k < baselineLayout.getChildCount(); k++) {
                        View baselineChild = baselineLayout.getChildAt(k);
                        if (baselineChild instanceof TextView) {
                            TextView textView = (TextView) baselineChild;
                            textView.setTypeface(avenirHeavy);
                        }
                    }
                }
            }
        }
    }

答案 9 :(得分:0)

如果您在 Asset 文件夹中有一个CustomFont,并且要在底部导航中进行设置,请使用此代码

  public class Font extends AppCompatActivity {
        public static void persian_iran_font(final Context context, final View v) {
            try {
                if (v instanceof ViewGroup) {
                    ViewGroup vg = (ViewGroup) v;
                    for (int i = 0; i < vg.getChildCount(); i++) {
                        View child = vg.getChildAt(i);
                        persian_iran_font(context, child);
                    }
                } else if (v instanceof TextView) {
                    ((TextView) v).setTypeface(Typeface.createFromAsset(context.getAssets(), "teshrinarmedium.otf"));
                }
            } catch (Exception e) {
            }
        }
    }

然后在MainActivity中使用Font类 像这样

  BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
    Font.persian_iran_font(getApplicationContext(), navigation);

祝你好运

答案 10 :(得分:0)

style.xml

<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

</style>
<style name="Widget.BottomNavigationView"
    parent="Widget.Design.BottomNavigationView">
    <item name="fontFamily">@font/segoe_ui_semibold</item>
</style>
</resources>

activity_main.xml

 <com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_navigation_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="#FFF"
    app:itemIconTint="@color/navigation_bottom"
    app:itemTextColor="@color/navigation_bottom"
    app:labelVisibilityMode="labeled"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    android:theme="@style/Widget.BottomNavigationView" (this line)
    app:menu="@menu/nav_items" />

答案 11 :(得分:0)

长话短说:

/**
 * @param view The bottom navigation view to update
 * @param tf The typeface which the text should be displayed
 */
public static void setAllTypefaces(View view, Typeface tf) {
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
            setAllTypefaces(((ViewGroup) view).getChildAt(i),tf);
    } else if (view instanceof TextView) ((TextView) view).setTypeface(tf);
}

enter image description here

相关问题