如何在Android工具栏中设置自定义字体标题

54

我正在做这件事:

toolbar = (Toolbar) findViewById(com.sports.unity.R.id.tool_bar);
setSupportActionBar(toolbar);
setTitle("hello");

我想为标题“hello”中的文本设置自定义字体。如何做到这一点?

24个回答

72

自从 android.support.v7.appcompat 24.2 版本,Toolbar 组件就有了 setTitleTextAppearance 方法,你可以不需要外部的 textview 组件来设置其字体。

在 styles.xml 中创建新样式。

<style name="RobotoBoldTextAppearance">
        <item name="android:fontFamily">@font/roboto_condensed_bold</item>
</style>

并使用它

mToolbar.setTitleTextAppearance(this, R.style.RobotoBoldTextAppearance);

6
最佳答案 - Goodlife
为了得到正确的答案,我会补充添加创建字体 xml 的链接:https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html - Fabrizio Caldarelli
1
只需要一行代码就解决了我的问题。谢谢! - Nirav Bhandari
1
也许可以像这样为样式添加一个父级:parent="TextAppearance.Widget.AppCompat.Toolbar.Title"。因为标题的大小对我来说太小了。 - Kevin van Mierlo
它对我起作用了。但是我在xml文件中实现了它,如下所示: app:titleTextAppearance="@style/ToolbarTextAppearance" - Jimmy ALejandro

65

更新2018年(kotlin版本)

fun Toolbar.changeToolbarFont(){
    for (i in 0 until childCount) {
        val view = getChildAt(i)
        if (view is TextView && view.text == title) {
            view.typeface = Typeface.createFromAsset(view.context.assets, "fonts/customFont")
            break
        }
    }
}

然后像这样使用它:toolBar.changeToolbarFont()

旧文章

要在工具栏中使用自定义标题,您只需要记住工具栏只是一个高级视图组,因此您可以像这样添加自定义标题:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/action_bar_bkgnd"
    app:theme="@style/ToolBarTheme" >


     <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Toolbar Title"
        android:layout_gravity="center"
        android:id="@+id/toolbar_title" />


    </android.support.v7.widget.Toolbar>
这意味着您可以随心所欲地样式化TextView,因为它只是一个普通的TextView。因此,在您的活动中,您可以像这样访问标题:
Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar_top);
TextView mTitle = (TextView) toolbarTop.findViewById(R.id.toolbar_title);

然后:

Typeface khandBold = Typeface.createFromAsset(BalrogApplication.getApplication().getAssets(), "fonts/Khand-bold.ttf");

mTitle.setTypeface(khandBold);

更新 动态版本

public static void changeToolbarFont(Toolbar toolbar, Activity context) {
    for (int i = 0; i < toolbar.getChildCount(); i++) {
        View view = toolbar.getChildAt(i);
        if (view instanceof TextView) {
            TextView tv = (TextView) view;
            if (tv.getText().equals(toolbar.getTitle())) {
                applyFont(tv, context);
                break;
            }
        }
    }
}

public static void applyFont(TextView tv, Activity context) {
    tv.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/customFont"));
}

然后像那样使用它

changeToolbarFont(findViewById(R.id.app_bar), this);

1
是的,我的活动还显示了TextView的类名。如何从中删除类名? - anupam x
@anupamx 您可以像这样删除操作栏: getSupportActionBar().setTitle(null); 在将工具栏设置为操作栏后立即执行此操作: setSupportActionBar(toolbar); - Bandreid
@gmetax 如果我在XML中将自定义TextView放置在工具栏内,那么我将无法使用工具栏的默认标题,对吗?我的意思是,我的调用toolbar.setTitle()将会徒劳无功,我是对的吗? - Mehmed
@Mehmed 是的,但是你可以重写那个方法以使其按照你的意愿工作。 - gmetax
动态的方法是唯一对我有效的。 - Learn OpenGL ES
这个对我来说一直都是有效的,直到我开始使用导航组件后,我不得不将 view.text == title 更改为 view.text == title.toString() - Edmund Johnson

37

我仍然希望使用工具栏标题方法(也不想拥有自定义的工具栏类),因此在工具栏XML元素中添加自定义TextView对我没有用。相反,我使用了以下方法来查找TextView:

public static void applyFontForToolbarTitle(Activity context){
    Toolbar toolbar = (Toolbar) context.findViewById(R.id.app_bar);
    for(int i = 0; i < toolbar.getChildCount(); i++){
        View view = toolbar.getChildAt(i);
        if(view instanceof TextView){
            TextView tv = (TextView) view;
            Typeface titleFont = Typeface.
               createFromAsset(context.getAssets(), "fonts/customFont");
            if(tv.getText().equals(toolbar.getTitle())){
                tv.setTypeface(titleFont);
                break;
            }
        }
    }
}

3
应该使用toolbar.getTitle()而不是context.getTitle()。谢谢!这对我有效。 - crubio
这帮助我在无法访问布局文件或向工具栏添加TextView的情况下设置自定义字体。 - Ícaro
如果您在代码中设置了工具栏标题字符串,请确保在设置工具栏标题后调用上述方法。在设置标题之前,它没有任何效果。 - abedfar
我唯一能提出的建议是,在设置字体时返回一个成功值。 - gmetax

24

你可以仅使用主题来完成此操作:

我写了一篇文章,详细介绍了解决方案。以下是基本步骤:

1)在styles.xml中定义一个主题:

<style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="android:fontFamily">@font/fancy-font</item>
</style>

2) 在你的Toolbar布局中设置该主题:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    android:theme="@style/ToolbarTheme"/>

这假设你已经在res/font文件夹中存储了一个.ttf字体文件:

带有字体的资源目录


18
在最新版本的Android Studio 3中,您可以在res目录下创建fonts文件夹。之后,您必须在styles.xml中定义自定义样式,并在工具栏中使用titleTextAppearance来应用所定义的样式。
请按以下步骤操作:
1. 创建fonts目录:res > Android Resource Directory > 资源类型:fonts,并单击“确定”以创建fonts目录(适用于Android Studio 3)。
2. 打开styles.xml并创建如下所示的自定义样式。
<style name="**TextAppearance.TabsFont**" parent="**android:TextAppearance**">
    <item name="android:fontFamily">font/rmedium</item>
    <item name="android:textSize">18sp</item>
</style>

3.现在打开布局并在工具栏标签中添加 app:titleTextAppearance="@style/TextAppearance.TabsFont",如下所示。

<android.support.v7.widget.Toolbar

    android:id="@+id/toolbarMain"
    app:title="@string/time_amp_date"
    app:titleTextAppearance="@style/TextAppearance.TabsFont"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    android:theme="@style/AppTheme"
    app:elevation="2dp" />

完成了DONE。现在,如果您运行应用程序,您可以看到字体设置为您的工具栏。


5
  1. Placement of Fonts:

    • Firstly, download a .ttf file. My file is Balker.ttf
    • make sure that you have got an "assets" folder. If there is none, right click over app go to New>Folder>assets Folder
    • In assets folder, create a new folder and name it 'font'
    • Put your file, as I did with Balker.ttf, into the 'font' folder.
  2. Go to the java file of the activity whose font you have to customize. I customized mainActivity here.

     for(int i = 0; i < toolbar.getChildCount(); i++)     
     { View view = toolbar.getChildAt(i);
    
        if(view instanceof TextView) {
            TextView textView = (TextView) view;
    
            Typeface myCustomFont=Typeface.createFromAsset(getAssets(),"font/Balker.ttf");
            textView.setTypeface(myCustomFont); }
    
    
     }
    

我认为使用XML属性会更好。app:titleTextAppearance="@style/ToolbarTextAppearance" - murt

4

两种方式可以在工具栏标题上使用自定义字体

解决方案1 [静态方法]

1)在styles.xml中定义一个主题:

  <style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Light">
      <item name="android:fontFamily">@font/ubuntu</item>
  </style>

2) 在您的工具栏布局中设置该主题:

   <android.support.v7.widget.Toolbar
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/toolbar"
     android:layout_width="match_parent"
     android:layout_height="?attr/actionBarSize"
     android:background="@color/colorPrimary"
     android:theme="@style/ToolbarTheme"/>

解决方案 2:[ 动态 ]

Kotlin

    fun Toolbar.titleFont(){
    for (i in 0 until childCount) {
        val view = getChildAt(i)
        if (view is TextView && view.text == title) {
            view.typeface = Typeface.createFromAsset(context.assets,"fonts/customfont.ttf")
            break
        }
    }
} 

然后像这样使用它:

   toolBar.titleFont()

3

如果你只想改变工具栏标题的字体,不需要使用外部textview,因为android.support.v7.appcompat 24.2Toolbar有一个方法setTitleTextAppearance,你可以像下面这样设置它的字体。

在styles.xml中创建一个新的样式。

<style name="CamptonBookTextAppearance">
     <item name="android:fontFamily">@font/campton_book</item>
</style>

并使用它

mToolbar.setTitleTextAppearance(this, R.style.CamptonBookTextAppearance);

1
简单的解决方案!谢谢 - Pooja

3
你可以使用这个简单的方法来为工具栏标题设置自定义字体。
 Toolbar   toolbar = (Toolbar) findViewById(com.sports.unity.R.id.tool_bar);
        TextView tv = getToolBarTextView();
        tv.settext("Hello");

private TextView getToolBarTextView() {
        TextView titleTextView = null;

        try {
            Field f = mToolBar.getClass().getDeclaredField("mTitleTextView");
            f.setAccessible(true);
            titleTextView = (TextView) f.get(mToolBar);

     Typeface font = Typeface.createFromAsset(getApplicationContext().getAssets(),"fonts/mfont.ttf");
    titleTextView.setTypeface(font);

        } catch (NoSuchFieldException e) {
        } catch (IllegalAccessException e) {
        }
        return titleTextView;
    }

反射在最好的情况下也是不可靠的。当启用缩小时,它对我来说失败了。 - afathman

2
我也搜索了这个问题,这是其中一个最先出现的答案。我会添加我的解决方案,因为这里给出的那个可以被视为有点过时(请记住,它仍然可以工作)。
由于Android现在支持自定义字体,所以没有理由在Java中分配字体,可以在制作XML文件时完成。
首先,在您的布局文件中,添加一个自定义工具栏(您可以在此处设置文本大小)。
<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar_top"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:background="@color/primary">
        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/signup"
            android:textSize="22sp" />
    </android.support.v7.widget.Toolbar>

然后,进入您的XML文件的设计选项卡,并在工具栏上选择文本。

Step 1

选择fontFamily选项并在给定的选项下选择所需的字体。如果没有给定,您可以搜索更多字体。

Step 2

搜索您想要的字体并选择它。您的字体将被更改。

Step 3

您的XML文件现在将反映您添加的字体,将有一个名为android:fontFamily的属性。
<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar_top"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:background="@color/primary">
        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="@font/roboto_slab"
            android:text="@string/signup"
            android:textColor="@color/secondaryBackground"
            android:textSize="22sp" />
    </android.support.v7.widget.Toolbar>

希望这有所帮助。

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