如何更改导航抽屉字体?

31

我希望在Android的导航抽屉中使用自己的字体。根据这个答案,我使用了Android Studio自带的库:https://dev59.com/uGEh5IYBdhLWcg3w_nuv#23632492。 但是我不知道如何更改字体并使其从右向左排版(RTL)。 我进行了大量搜索,发现了如何使抽屉从右向左排版。我使用了以下代码:

getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

并且 Android - 是否可以从右侧打开导航抽屉?

但是您知道,这仅适用于API 17及以上版本。 请帮忙!如何更改菜单字体?如何以正确的方式将布局设置为RTL?!

编辑:: 我的字体“TTF”文件位于assets / fonts中,我知道如何在Java中为TextView设置它,但我不知道如何将其设置为导航抽屉菜单。


你是否使用自定义的XML行来管理菜单?如果是,我可以告诉你如何更改菜单文本字体。 - Tanim reja
@Tanimreja 是的,我做到了! - Amir H
7个回答

69

你可以用更简单的方法来完成这个操作。

首先进入style.xml文件,在其中创建一个新的样式。

 <style name="RobotoTextViewStyle" parent="android:Widget.TextView">
      <item name="android:fontFamily">@font/sans-serif-smallcaps</item>
 </style>

第二步是前往您的导航 XML 代码并在此处放置项目文本外观

app:itemTextAppearance="@style/RobotoTextViewStyle"

现在你的最终导航代码应该是这样的。

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:itemTextAppearance="@style/RobotoTextViewStyle"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_home"
        app:menu="@menu/activity_home_drawer" />

2
希望我能点赞两次,这不应该是一个代码解决方案... 而是 XML。 - vin shaba
1
先生,您是一个传奇。非常感谢您提供的答案。 - Sumukha Aithal K
是的,你应该得到两个赞。 - Tarique Anowar

40

我找到了答案:
首先在你的项目中创建这个类:

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {

    private final Typeface newType;

    public CustomTypefaceSpan(String family, Typeface type) {
        super(family);
        newType = type;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, newType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, newType);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
        } else {
            oldStyle = old.getStyle();
        }

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}

然后将此方法添加到您想要更改导航抽屉菜单字体的活动中:

private void applyFontToMenuItem(MenuItem mi) {
        Typeface font = Typeface.createFromAsset(getAssets(), "ds_digi_b.TTF");
        SpannableString mNewTitle = new SpannableString(mi.getTitle());
        mNewTitle.setSpan(new CustomTypefaceSpan("" , font), 0 , mNewTitle.length(),  Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        mi.setTitle(mNewTitle);
}

然后在你的活动中调用你刚刚添加的方法:

navView = (NavigationView) findViewById(R.id.navView);
Menu m = navView.getMenu();
for (int i=0;i<m.size();i++) {
    MenuItem mi = m.getItem(i);

    //for aapplying a font to subMenu ...
    SubMenu subMenu = mi.getSubMenu();
    if (subMenu!=null && subMenu.size() >0 ) {
        for (int j=0; j <subMenu.size();j++) {
            MenuItem subMenuItem = subMenu.getItem(j);
            applyFontToMenuItem(subMenuItem);
        }
    }

    //the method we have create in activity
    applyFontToMenuItem(mi);
}

很好。但是如何将方向从左到右改变为从右到左(RTL)呢?我的意思是对于所有的API都进行设置,而不仅仅是17及以上的版本? - Hossein Mansouri
@HosseinMansouri 在这种情况下,您必须手动将抽屉添加到您的项目中,而不是使用Google导航抽屉库。 - Amir H
任何抽屉的示例? - Hossein Mansouri
@HosseinMansouri 当然可以找到,谷歌一下就好啦。 :)) - Amir H

14

步骤1:在style.xml中设置样式如下

<style name="NavigationView" >
<item name="fontFamily">@font/helvetica_neue_light</item>
</style>

步骤2:将样式添加为主题到您的android.support.design.widget.NavigationView中

android:theme="@style/NavigationView"


谢谢,它非常好用和简单,而且不需要创建任何其他的类!!! - Ali Khaki
没有父样式可以继承吗? - Someone Somewhere
2
更新:不需要父样式。安卓在这方面的一致性很奇怪。 - Someone Somewhere

10

补充rischan的答案。

我直接编辑了'mi',因为那些是我的抽屉菜单标题。然后,我将s.setSpan的第一个参数更改为使用自定义类CustomTypefaceSpan。

    // Navigation View
    NavigationView navigationView = (NavigationView) 
    findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    Menu m = navigationView .getMenu();

    Typeface tf1 = Typeface.createFromAsset(getAssets(), "font/Gotham Narrow Extra Light.otf");

    for (int i=0;i<m.size();i++) {

        MenuItem mi = m.getItem(i);

        SpannableString s = new SpannableString(mi.getTitle());
        s.setSpan(new CustomTypefaceSpan("", tf1), 0, s.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        mi.setTitle(s);

    }

CustomTypefaceSpan类:

package my.app;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {

    private final Typeface newType;

    public CustomTypefaceSpan(String family, Typeface type) {
        super(family);
        newType = type;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeFace(ds, newType);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeFace(paint, newType);
    }

    private static void applyCustomTypeFace(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        if (old == null) {
            oldStyle = 0;
        } else {
            oldStyle = old.getStyle();
        }

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}

简直无法相信只是更改菜单字体有多么复杂。


+1 给自定义字体的努力,并为子菜单添加字体,以便整个导航菜单有清晰明确的答案。 - brahmy adigopula

7
感谢您!根据@Amir H的帖子,我已成功更改了导航抽屉上的字体,但需要进行配置(将以下几行添加到您的活动中即可)。
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        Menu m = navigationView .getMenu();

        for (int i=0;i<m.size();i++) {
            MenuItem mi = m.getItem(i);

            //for applying a font to subMenu ...
            SubMenu subMenu = mi.getSubMenu();
            if (subMenu!=null && subMenu.size() >0 ) {
                for (int j=0; j <subMenu.size();j++) {
                    MenuItem subMenuItem = subMenu.getItem(j);
                    SpannableString s = new SpannableString(subMenuItem.getTitle());
                    s.setSpan(new TypefaceSpan("fonts/yourfontname.ttf"), 0, s.length(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    subMenuItem.setTitle(s);
                }
            }

        }

也许这能帮到某些人 :)

4

仅适用于字体

  1. First Of All Add color of your font (if you want to change) in colors.xml file located at res->values->colors.xml like

    <color name="black">#000000</color> // it's for black don't go for white color
    
  2. Then edit style.xml file located at same values directory (there are two files edit that file which having your theme with style name="your_theme" or find line in that two file

  3. Here we have to set font property. So you have to create new style tag in enclosing resource tags. in my case I create

    <style name="MyText" parent="@android:style/TextAppearance.Medium">
        <item name="android:textSize">20sp</item> //size of font
        <item name="android:textColor">@color/black</item> //color of font
        <item name="android:typeface">sans</item> // type how it appear
    </style>
    

    Note that Name given for this tag is MyText. Now we have to use this name in aboved first style block whose name is your appication theme.

  4. Mentioned this new style in above appication theme style tag. In my case its like

    <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
            <item name="android:textViewStyle">@style/MyText</item> //MyText its custom style for font
        </style>
    

@Abishek,它并没有改变字体。它只改变了大小和颜色。当然,导航抽屉也没有改变!此外,我的字体文件在assets/fonts文件夹中。 - Amir H

1

首先,在res>>values文件夹下创建一个名为style.xml的XML文件。

然后,在<resource><style name="mynavigationfont" > <item name="fontFamily">@font/sans-serif</item> </style> </resource>下方复制并添加以下代码:

注意:将此代码添加在<resource ...这里.. if >中。

<?xml version="1.0" encoding="UTF-8"?>

如果不加这个,可能会显示错误

最后,在你的XML中添加这个

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:itemTextAppearance="@style/RobotoTextViewStyle"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_home"
    app:menu="@menu/activity_home_drawer" />

这行代码 - app:itemTextAppearance="@style/mynavigationfont"



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接