11

I want to change font-family of my toolbar title to sans-serif-smallcaps. How do I do it?

My AppTheme has parent Theme.AppCompat.Light.DarkActionBar

Edit: Toolbar 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" />
RandomyzeEverything
  • 764
  • 3
  • 7
  • 21
  • 1
    If you are using `Toolbar` then my answer is the best answer I can guarantee of that. Because even I am using `Toolbar`, just provide title using `toolbar.getTitle()`. I don't know why it has been marked down as negative, but I am sure it will help you. – Jimit Patel Apr 04 '17 at 12:05
  • If you want to get preloaded list of fonts have a look at this solution, http://stackoverflow.com/a/29533686/842607 It also describes which typeface using which ttf file. And also they have given demo of how to use `Reflection` in it – Jimit Patel Apr 04 '17 at 12:08
  • @RandomyzeEverything See my answer below and also see the attached image for output. – Ferdous Ahamed Apr 04 '17 at 12:15

6 Answers6

20

My Layout Page:

<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>

Go to Your styles.xml then add your font (This is works in 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>
ROY VARGHESE
  • 279
  • 3
  • 5
  • my main theme is Theme.AppCompat.Light.NoActionBar I tried to change parent of toolbar style to ThemeOverlay.AppCompat.Ligh as there is no overlay with NoActionBar but the font is never changed. Do you know how to do it? Thanks. – Pablo R. Apr 23 '19 at 09:29
  • finally worked changing from app:popupTheme to android:theme – Pablo R. Apr 23 '19 at 09:44
  • you just set `TextAppearance` instead of the whole `popupTheme` – user924 Aug 12 '22 at 11:43
2

# To Use default Android Font-Family:

In your Toolbar XML, add a child TextView to show the Title. Set android font-family to TextView using attribute android:fontFamily="sans-serif-smallcaps"

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>

# To Use External Font:

  1. Put external font file into location: .../app/src/main/assets/fonts/YOUR_CUSTOM_FONT.ttf

  2. Add below codes in your Activity to set custom font to Toolbar title.

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);
    }

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

OUTPUT:

enter image description here

Hope this will help~

Ferdous Ahamed
  • 21,438
  • 5
  • 52
  • 61
  • I want to use a font which is built in, because in my other XMLs, I just use `android:fontFamily="sans-serif-smallcaps"`, how do I use it in your code? – RandomyzeEverything Apr 04 '17 at 12:20
  • @RandomyzeEverything see my updated answer "To Use default Android Font-Family". Hope this will work for you. – Ferdous Ahamed Apr 04 '17 at 17:19
  • The problem with this approach is that it does not work with collapsing toolbar. An addition toolbar title is just pinned to the top. – andras Dec 13 '17 at 15:23
1

It works fine.

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);
            }
        }
    });
w568w
  • 113
  • 1
  • 10
1

Place your font file (.ttf) in assets folder and write following code in Activity class.

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

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

text.setTypeface(font);

Update

You are right in getting the textview with getChildAt(0)..but I don't know why the font didn't apply to title. but my guess is you need to set font before setting 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);
sravs
  • 330
  • 2
  • 14
  • Why do I need to put my font file in assets folder? In my other XMLs, I just use `android:fontFamily="sans-serif"` so isn't it kind of inbuilt? And also can I get `TextView` by using `TextView textView = (TextView) toolbar.getChildAt(0)`? – RandomyzeEverything Apr 04 '17 at 11:46
  • I thought u have .ttf file.so you can directly use it in the same way to toolbar title in xml..didn't that work? – sravs Apr 04 '17 at 11:54
  • 1
    @RandomyzeEverything Check my code, in that you can use this line `toolbarTitle.setSpan(Typeface.SANS_SERIF, 0 , toolbarTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);` and remove `CustomTypefaceSpace` class from it – Jimit Patel Apr 04 '17 at 11:58
  • @sravs Added my XML – RandomyzeEverything Apr 04 '17 at 12:04
  • @JimitPatel A perfect answer. But why did you posted it as a comment? You should post as an answer. – Riddhi Shah May 21 '18 at 04:56
1

Create a SpannableString object and pass the font path from asset. Check the working below

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);

Here, R.string.circular_bold is

<string name="circular_bold">font/CircularStd-Bold.ttf</string>

And font is in Asset/font folder as displayed in image below

enter image description here

Below CustomFontHelper class helps to set Typeface to the text element-

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 class is the actual class where font is applied to the text element.

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 class is for caching the font, so same font can be reused 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
  • 4,265
  • 2
  • 34
  • 58
1

For material toolbar, Add a style in your themes.xml like below:

  <style name="toolbar_text">

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

    </style>

then in your Material toolbar, add it to app:titleTextAppearance="@style/toolbar_text"

like below

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

        ...

        app:titleTextAppearance="@style/toolbar_text" />
Rahat Shah
  • 119
  • 1
  • 4