Android toolbar center title and custom font

432,758

Solution 1

To use a custom title in your Toolbar all you need to do is remember is that Toolbar is just a fancy ViewGroup so you can add a custom title like so:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_top"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?android: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>

This means that you can style the TextView however you would like because it's just a regular TextView. So in your activity you can access the title like so:

Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar_top);
TextView mTitle = (TextView) toolbarTop.findViewById(R.id.toolbar_title);

Solution 2

This's just to help to join all pieces using @MrEngineer13 answer with @Jonik and @Rick Sanchez comments with the right order to help to achieve title centered easly!!

The layout with TextAppearance.AppCompat.Widget.ActionBar.Title :

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

        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"                      
            style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
            android:layout_gravity="center" />

    </android.support.v7.widget.Toolbar>

The way to achieve with the right order:

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);

    setSupportActionBar(toolbar);
    mTitle.setText(toolbar.getTitle());

    getSupportActionBar().setDisplayShowTitleEnabled(false);

Please don't forget to upvote @MrEngineer13 answer !!!

Here is a sample project ToolbarCenterTitleSample

enter image description here

Hope to help somebody else ;)

Solution 3

The ToolBar title is stylable. Any customization you make has to be made in the theme. I'll give you an example.

Toolbar layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    style="@style/ToolBarStyle.Event"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    android:minHeight="@dimen/abc_action_bar_default_height_material" />

Styles:

<style name="ToolBarStyle" parent="ToolBarStyle.Base"/>

<style name="ToolBarStyle.Base" parent="">
    <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
    <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
</style>

<style name="ToolBarStyle.Event" parent="ToolBarStyle">
    <item name="titleTextAppearance">@style/TextAppearance.Widget.Event.Toolbar.Title</item>
</style>

<style name="TextAppearance.Widget.Event.Toolbar.Title" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
    <!--Any text styling can be done here-->
    <item name="android:textStyle">normal</item>
    <item name="android:textSize">@dimen/event_title_text_size</item>
</style>

Solution 4

we don't have direct access to the ToolBar title TextView so we use reflection to access it.

  private TextView getActionBarTextView() {
    TextView titleTextView = null;

    try {
        Field f = mToolBar.getClass().getDeclaredField("mTitleTextView");
        f.setAccessible(true);
        titleTextView = (TextView) f.get(mToolBar);
    } catch (NoSuchFieldException e) {
    } catch (IllegalAccessException e) {
    }
    return titleTextView;
}

Solution 5

Define the following class:

public class CenteredToolbar extends Toolbar {

    private TextView centeredTitleTextView;

    public CenteredToolbar(Context context) {
        super(context);
    }

    public CenteredToolbar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CenteredToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setTitle(@StringRes int resId) {
        String s = getResources().getString(resId);
        setTitle(s);
    }

    @Override
    public void setTitle(CharSequence title) {
        getCenteredTitleTextView().setText(title);
    }

    @Override
    public CharSequence getTitle() {
        return getCenteredTitleTextView().getText().toString();
    }

    public void setTypeface(Typeface font) {
        getCenteredTitleTextView().setTypeface(font);
    }

    private TextView getCenteredTitleTextView() {
        if (centeredTitleTextView == null) {
            centeredTitleTextView = new TextView(getContext());
            centeredTitleTextView.setTypeface(...);
            centeredTitleTextView.setSingleLine();
            centeredTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
            centeredTitleTextView.setGravity(Gravity.CENTER);
            centeredTitleTextView.setTextAppearance(getContext(), R.style.TextAppearance_AppCompat_Widget_ActionBar_Title);

            Toolbar.LayoutParams lp = new Toolbar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            lp.gravity = Gravity.CENTER;
            centeredTitleTextView.setLayoutParams(lp);

            addView(centeredTitleTextView);
        }
        return centeredTitleTextView;
    }
}

...and then just use it instead of regular Toolbar like this:

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent">

        <your.packagename.here.CenteredToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            android:theme="?attr/actionBarTheme"
            app:title="@string/reset_password_page_title"/>

        <!-- Other views -->

</RelativeLayout>

You still need these 2 lines of code in your Activity (as with standard Toolbar):

Toolbar toolbar = (Toolbar) findViewByid(R.id.toolbar); // note that your activity doesn't need to know that it is actually a custom Toolbar
setSupportActionBar(binding.toolbar);

That's it! You don't need to hide the standard left-aligned title, don't need to duplicate the same XML code over and over, etc., just use CenteredToolbar like if it was default Toolbar. You can also set your custom font programatically since you now have direct access to the TextView. Hope this helps.

Share:
432,758
Mathbl
Author by

Mathbl

Updated on December 30, 2021

Comments

  • Mathbl
    Mathbl over 2 years

    I'm trying to figure out the right way to use a custom font for the toolbar title, and center it in the toolbar (client requirement).

    At the moment, i'm using the good old ActionBar, and I was setting the title to empty value, and using setCustomView to put my custom font TextView and center it using ActionBar.LayoutParams.

    Is there a better way to do that? Using the new Toolbar as my ActionBar.

  • SteelBytes
    SteelBytes over 9 years
    suggest use android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" instead.
  • falc0nit3
    falc0nit3 over 9 years
    Although this is hacky, this solution works for me after trying to find a way to get access to the toolbar textview. Thank you.
  • matiash
    matiash over 9 years
    Is this only when using a custom toolbar instead of the provided one? Otherwise how do you get access to the Toolbar object (mToolbar here)?
  • Oknesif
    Oknesif over 9 years
    This is shame, that in the material design guides the title has padding, but it doesn't by default and we even don't have access to the mTitleView. Thank for your answer.
  • goRGon
    goRGon over 9 years
    Sometimes android:layout_gravity="top" works better for me to align a title TextView with Toolbar's <- arrow.
  • Vinod
    Vinod about 9 years
    Worked nicely for the Title. But when tried to obtain the mSubtitleTextView like this, it resulted in an exception. Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setTypeface(android.graphics.Typefac‌​e)' on a null object reference
  • Doronz
    Doronz about 9 years
    This method did not work for me. The title is already set to be the app name.
  • MrEngineer13
    MrEngineer13 about 9 years
    You can clear the title text either programmatically with toolbarTop.setTitle(null) or you can remove the label from your manifest
  • porthfind
    porthfind about 9 years
    This also didn't work for me..it appears the name of the app and I have removed the label of the activity in manifest
  • Rick Sanchez
    Rick Sanchez about 9 years
    If anyone else can't remove the default app name title, do this: 1. Call setSupportActionBar(yourToolbar) 2. Call getSupportActionBar().setDisplayShowTitleEnabled(false);
  • BugsBunnyBR
    BugsBunnyBR about 9 years
    for the subtitle you should use "mSubtitleText", not "mSubtitleTextView"
  • Jonik
    Jonik about 9 years
    To keep using default styles for the customised TextView, try something like style="@style/TextAppearance.AppCompat.Widget.ActionBar.Titl‌​e" (see this answer).
  • Admin
    Admin almost 9 years
    you answer is so great, BUT, android:paddingTop="@dimen/tool_bar_top_padding" never center text, because point of center of row, It is displaced.
  • Admin
    Admin almost 9 years
    if you want use a getActionBarTextView().setGravity(Gravity.CENTER) this method or into method textview , java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setGravity(int)' on a null object reference
  • funcoder
    funcoder almost 9 years
    Note: You can only access the "mTitleTextView" field, after you set the toolbar title! The field is lazy initialized by its first use.
  • Daniele D.
    Daniele D. over 8 years
    This solution saved my day and it works also for Xamarin.
  • Ankur Chaudhary
    Ankur Chaudhary over 8 years
    Using textview inside toolbar causing problem with search widget in toolbar. If i use search widget in toolbar, on click of search icon it increase height of toolbar to nearby half of screen height but as i remove that textview from toolbar it start working properly. Any idea?
  • GreenROBO
    GreenROBO over 8 years
    @MrEngineer13 I'm not able to apply this for CollapsingToobarLayout. Any suggestions???
  • Johann
    Johann about 8 years
    None of this worked for me. Possibly because my toolbar includes a menu, which causes Android to ditch the TextView layout for the title.
  • saiyancoder
    saiyancoder almost 8 years
    You may also remove the default app name title by using an empty android:label in the AndroidManifest declaration.
  • voghDev
    voghDev over 7 years
    What if you obfuscate your code with ProGuard and mTitleTextView becomes abcde12345?
  • Gordak
    Gordak over 7 years
    adding android:paddingRight="?attr/actionBarSize" can help to center the text in the middle of your screen in the case you have a button (home, navigation drawer, etc)
  • DariusL
    DariusL over 7 years
    Downvoted this a year ago, because using styles is cleaner. But if you need a custom font, this is the best way. Just did the same thing. Though, you'll need a bit more configuration to make sure your activity title is set on the correct view.
  • Akshay
    Akshay over 7 years
    What will be happened when there is Hamburger icon on Toolbar? It will be not in center of complete toolbar width, it will be in center of ToolbarWidth - HamburgerIconWidth.
  • Jeremy
    Jeremy over 7 years
    @voghDev getDeclaredField will throw NoSuchFieldException in that case, resulting in the code not working.
  • Meanman
    Meanman over 7 years
    Only way to get a custom font as far as I was able to try.
  • SAYE
    SAYE about 7 years
    This answer is not a good idea because you can't use it in a scrolling activity when you scroll down the custom Textview will hide and original title is shown! you can test it ! is answer is very confusing .
  • Siavash
    Siavash about 7 years
    for me, layout_gravity doesn't work in toolbar. it doesn't show up in auto-complete, and when I manually type it in, it does nothing.
  • breakline
    breakline about 6 years
    Why is this the accepted answer when it clearly doesn't work?
  • Vinay
    Vinay about 6 years
    @voghDev place mTitleTextView in strings.xml and use it in code.
  • ductran
    ductran over 5 years
    @Akshay try to move TextView into a FrameLayout wrap in toolbar
  • Carson Holzheimer
    Carson Holzheimer over 5 years
    I had to use androidx.appcompat.widget.Toolbar to be able to put a Textview inside the toolbar
  • MobDev
    MobDev almost 4 years
    I get a warning when going with this approach requestLayout() improperly called by com.google.android.material.textview...during layout: running second layout pass