如何更改工具栏标题的字体?

11

我想把工具栏标题的字体族改成sans-serif-smallcaps,我该怎么做?

我的AppTheme继承自Theme.AppCompat.Light.DarkActionBar

编辑: 工具栏 XML:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

1
如果你正在使用Toolbar,那么我的答案是最好的答案,我可以保证这一点。因为即使我自己也在使用Toolbar,只需使用toolbar.getTitle()来提供标题。我不知道为什么它被评为负面,但我确信它会对你有所帮助。 - Jimit Patel
如果你想获取预加载字体列表,请查看这个解决方案,https://dev59.com/-2ct5IYBdhLWcg3wZMfn#29533686。它还描述了使用哪种TTF文件的字体类型。而且他们还演示了如何在其中使用“反射”。 - Jimit Patel
@RandomyzeEverything 请看下面的回答,还可以查看附加的图像以获取输出。 - Ferdous Ahamed
6个回答

20

我的布局页面:

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>

进入您的 styles.xml 文件,然后添加您的字体(此方法适用于Android Studio 3.0)

 <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" >
        <item name="android:fontFamily">@font/handlee_regular</item>
/// change your font
</style>

我的主题是Theme.AppCompat.Light.NoActionBar。我尝试将工具栏样式的父级更改为ThemeOverlay.AppCompat.Light,因为没有与NoActionBar重叠的覆盖,但字体从未更改。你知道怎么做吗?谢谢。 - Pablo R.
最终成功了,将“app:popupTheme”更改为“android:theme”。 - Pablo R.
你只需要设置TextAppearance而不是整个popupTheme - user924

2

对于材料设计工具栏,请在您的themes.xml中添加以下样式:

  <style name="toolbar_text">

        <item name="android:fontFamily">@font/font_name</item>
        <item name="android:textSize">20sp</item>

    </style>

然后在您的材料工具栏中将其添加到app:titleTextAppearance="@style/toolbar_text",如下所示:

   <com.google.android.material.appbar.MaterialToolbar

        ...

        app:titleTextAppearance="@style/toolbar_text" />

2

# 使用默认的Android字体:

在您的工具栏(Toolbar) XML 中,添加一个子TextView来显示标题(Title)。使用属性android:fontFamily="sans-serif-smallcaps"将 Android 字体族设置为 TextView

工具栏(Toolbar):

    <android.support.v7.widget.Toolbar
        android:id="@+id/oolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_collapseMode="pin"
        app:popupTheme="?attr/colorPrimaryDark" >

        <TextView
            android:id="@+id/custom_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Stack Overflow"
            android:textColor="#FFFFFF"
            android:textSize="20sp"
            android:textStyle="bold"
            android:fontFamily="sans-serif-smallcaps" />
    </android.support.v7.widget.Toolbar>

# 使用外部字体:

  1. 将外部字体文件放置在此位置:.../app/src/main/assets/fonts/YOUR_CUSTOM_FONT.ttf

  2. 在您的Activity中添加以下代码,将自定义字体设置为Toolbar标题。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Toolbar
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

        // Custom title
        TextView textCustomTitle = (TextView) findViewById(R.id.custom_title);

        // Custom font
        Typeface customFont = Typeface.createFromAsset(this.getAssets(), "fonts/Exo2-BoldItalic.ttf");

        // Set
        textCustomTitle.setTypeface(customFont);

        setSupportActionBar(toolbar);
    }

    .......
    ..............
}

输出:

进入图像描述

希望这能有所帮助~


我想使用内置的字体,因为在我的其他XML中,我只是使用android:fontFamily="sans-serif-smallcaps",请问如何在您的代码中使用它? - RandomyzeEverything
@RandomyzeEverything,请查看我的更新答案“使用默认的Android字体系列”。希望这对你有用。 - Ferdous Ahamed
这种方法的问题在于它无法与折叠工具栏一起使用。附加的工具栏标题只会固定在顶部。 - andras

1

它运行良好。

mToolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            View view = mToolbar.getChildAt(0);
            if (view != null && view instanceof TextView) {
                TextView title = (TextView) view;
                AssetManager mgr = getAssets();
                Typeface tf = Typeface.createFromAsset(mgr, "ttf.ttf");//Font file in /assets
                title.setTypeface(tf);
                mToolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        }
    });

1

将您的字体文件(.ttf)放入assets文件夹中,并在Activity类中编写以下代码。

Typeface font = Typeface.createFromAsset(getContext().getAssets(), "sansSmallCaps.ttf");

TextView text = (TextView) findViewById(R.id.toolbartitle);

text.setTypeface(font);

更新

你是对的,使用getChildAt(0)获取textview。但我不知道为什么字体没有应用到标题上。但我的猜测是在设置setSupportActionBar(myToolbar);之前需要设置字体。

Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
myToolbar.setTitle("xyz");
TextView tv=(TextView) myToolbar.getChildAt(0);
tv.setTypeface(Typeface.SANS_SERIF);
setSupportActionBar(myToolbar);

为什么我需要将字体文件放在资产文件夹中?在我的其他XML文件中,我只需使用android:fontFamily="sans-serif",这不是内置的吗?另外,我可以通过使用TextView textView = (TextView) toolbar.getChildAt(0)来获取TextView吗? - RandomyzeEverything
我以为你有.ttf文件。所以你可以直接在xml中的工具栏标题中使用它。这样行不行? - sravs
1
@RandomyzeEverything 请检查我的代码,在其中您可以使用这一行 toolbarTitle.setSpan(Typeface.SANS_SERIF, 0, toolbarTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); 并将其中的 CustomTypefaceSpace 类移除。 - Jimit Patel
@sravs 我添加了我的 XML。 - RandomyzeEverything
@JimitPatel 绝妙的回答。但是你为什么把它发布为评论呢?你应该发布为答案。 - Riddhi

1
创建一个SpannableString对象,并从资产中传递字体路径。请查看下面的工作情况。
SpannableString toolbarTitle = new SpannableString(getActionBar().getTitle());
        String toolbarFont = getResources().getString(R.string.circular_bold);
        CustomTypefaceSpan toolbarTypefaceSpan = new CustomTypefaceSpan(toolbarFont, this);
        toolbarTitle.setSpan(toolbarTypefaceSpan, 0, toolbarTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        getActionBar().setTitle(toolbarTitle);

这里,R.string.circular_bold 是什么。
<string name="circular_bold">font/CircularStd-Bold.ttf</string>

字体在下面图片中显示的Asset/font文件夹中。

enter image description here

以下CustomFontHelper类有助于将Typeface设置到文本元素中-
public class CustomFontHelper {

    /**
     * Changing font of Paint element
     * @param paint text element of which font needs to be changed
     * @param font
     * @param context
     */
    public static void setCustomFont(Paint paint, String font, Context context) {
        if (font == null) {
            return;
        }
        Typeface typeface = FontCache.get(font, context);
        if (typeface != null) {
            paint.setTypeface(typeface);
        }
    }
}

CustomTypefaceSpan类是实际应用字体到文本元素的类。

public class CustomTypefaceSpan extends TypefaceSpan {

    private String font;
    private Context context;

    public CustomTypefaceSpan(@NonNull String font, @NonNull Context context) {
        super("");
        this.font = font;
        this.context = context;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        CustomFontHelper.setCustomFont(ds, font, context);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        CustomFontHelper.setCustomFont(paint, font, context);
    }
}

FontCache类用于缓存字体,因此可以重复使用相同的字体。 public class FontCache {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    /**
     * Gets the typeface from Asset folder
     * @param name path to the font within asset folder
     * @param context context of the view
     * @return
     */
    public static Typeface get(String name, Context context) {
        Typeface tf = fontCache.get(name);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(context.getAssets(), name);
            } catch (Exception e) {
                return null;
            }
            fontCache.put(name, tf);
        }
        return tf;
    }
}

标记负数有什么意义??我已经在我的项目中使用它了,而且它完美地工作。 - Jimit Patel

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