Umesh Kumar Saraswat
Umesh Kumar Saraswat

Reputation: 768

Android: How to Center title in ToolBar

I am using ToolBar in my project first time, so i do not know how to customized the toolbar in android. I need to centered title in to the tool bar and how to do that please tell me.

Thank in advance.

Upvotes: 22

Views: 103449

Answers (20)

kd e
kd e

Reputation: 11

You can use MaterialToolbar and set app:titleCentered="true" in the xml.

Upvotes: 1

Tuan Dang Van
Tuan Dang Van

Reputation: 151

You can use MaterialToolbar, it supported on android material:1.4.0-alpha02

https://github.com/material-components/material-components-android/commit/cbf528e3a6deaa2bc39d0836b3a850b27c2ada49.

    implementation 'com.google.android.material:material:1.4.0-alpha02'
<com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:titleCentered="true" />

Upvotes: 6

Emek Cohen
Emek Cohen

Reputation: 283

for kotlin users from @user2137020 answer:

package com.example.safetyofficer.view

import android.content.Context
import android.util.AttributeSet
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import com.example.safetyofficer.R


class CustomToolbar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = R.attr.toolbarStyle
) :
    Toolbar(context, attrs, defStyleAttr) {
    private val titleView: TextView = TextView(getContext())

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
        titleView.x = (width - titleView.width) / 2.toFloat()
    }

    override fun setTitle(title: CharSequence) {
        titleView.text = title
    }

    init {
        val textAppearanceStyleResId: Int
        val a = context.theme.obtainStyledAttributes(
            attrs,
            intArrayOf(R.attr.titleTextAppearance),
            defStyleAttr,
            0
        )
        textAppearanceStyleResId = try {
            a.getResourceId(0, 0)
        } finally {
            a.recycle()
        }
        if (textAppearanceStyleResId > 0) {
            titleView.setTextAppearance(textAppearanceStyleResId)
        }
        addView(titleView, LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT))
    }
}

Upvotes: 0

Ness Tyagi
Ness Tyagi

Reputation: 2028

In koltin Just one function can help you out...

    private fun centerTitle(toolbar: Toolbar) {
    // Save current title
    val originalTitle: CharSequence = toolbar.title
    // Temporarily modify title
    toolbar.title = "title"
    for (i in 0 until toolbar.childCount) {
        val view: View = toolbar.getChildAt(i)
        if (view is TextView) {
            if (view.text == "title") {
                // Customize title's TextView
                val params: Toolbar.LayoutParams = Toolbar.LayoutParams(
                    Toolbar.LayoutParams.WRAP_CONTENT,
                    Toolbar.LayoutParams.MATCH_PARENT
                )
                params.gravity = Gravity.CENTER_HORIZONTAL
                view.layoutParams = params
            }
        }
        // Restore title
        toolbar.title = originalTitle
    }
}

Upvotes: 0

Manas Swain
Manas Swain

Reputation: 25

This did my work!

Toolbar toolbar = findViewById(R.id.mytoolbar);
        TextView titleText = getProperties(new TextView(this));
        FrameLayout frameLayout = new FrameLayout(this);
        frameLayout.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
        frameLayout.addView(titleText);
        toolbar.addView(frameLayout);
        setSupportActionBar(toolbar);

Method to Set TextView Properties

 private TextView getProperties(TextView titleText){
        titleText.setText(wallpaperName);
        titleText.setTextColor(Color.WHITE);
        titleText.setTextSize(18f);
        titleText.setShadowLayer(2f,2f,2f,Color.BLACK);
        titleText.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); // CENTER ALIGNMENT
        return titleText;
    }

Upvotes: 0

Sourav Bagchi
Sourav Bagchi

Reputation: 746

I slightly modified the Toolbar source to make the title centre aligned.

public class CenterTitleToolbar extends Toolbar {
    private AppCompatTextView titleTextView;


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

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

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

    @Override
    public void setTitle(CharSequence title) {
        if (!TextUtils.isEmpty(title)) {
            if (titleTextView == null) {
                final Context context = getContext();
                titleTextView = new AppCompatTextView(context);
                titleTextView.setSingleLine();
                titleTextView.setEllipsize(TextUtils.TruncateAt.END);
                titleTextView.setTextAppearance(context, R.style.TextAppearance_MaterialComponents_Headline6);
                final LayoutParams lp = generateDefaultLayoutParams();
                lp.gravity = Gravity.CENTER;
                titleTextView.setLayoutParams(lp);
            }
            if (titleTextView.getParent() != this) {
                addSystemView(titleTextView);
            }
        } else if (titleTextView != null && titleTextView.getParent() == this) {
            removeView(titleTextView);
        }
        if (titleTextView != null) {
            titleTextView.setText(title);
        }
    }

    private void addSystemView(View v) {
        final ViewGroup.LayoutParams vlp = v.getLayoutParams();
        final LayoutParams lp;
        if (vlp == null) {
            lp = generateDefaultLayoutParams();
        } else if (!checkLayoutParams(vlp)) {
            lp = generateLayoutParams(vlp);
        } else {
            lp = (LayoutParams) vlp;
        }
        addView(v, lp);
    }

}

Text Style TextAppearance_MaterialComponents_Headline6 is included in the new Android Material library.

Upvotes: 4

Vikram Singh
Vikram Singh

Reputation: 162

Based on @LiuWenbin_NO,

I had created a custom toolbar, which didn't need any extra view to center title in textview,

import android.content.Context
import android.util.AttributeSet
import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import android.view.Gravity

class CenteredToolbar(context: Context, attrs: AttributeSet?, defStyleAttr: Int):
Toolbar(context, attrs, defStyleAttr) {

constructor(context: Context) : this(context, null, 0)

constructor(context: Context, attrs: AttributeSet) : this(context, attrs, androidx.appcompat.R.attr.toolbarStyle)

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
    super.onLayout(changed, l, t, r, b)

    val childCount = childCount
    for (i in 0 until childCount) {
        val view = this.getChildAt(i)
        if (view is TextView) {
            forceTitleCenter(view,l, r)
            break
        }
    }
}

/**
 * Centering the layout.
 *
 * @param view The view to be centered
 */
private fun forceTitleCenter(view: TextView, l: Int,  r: Int) {
    val top = view.getTop()
    val bottom = view.getBottom()
    view.layout(l, top, r, bottom)
    navigationIcon?.let{
        view.setPadding(it.intrinsicWidth,0,0,0)
    }
    view.gravity = Gravity.CENTER
}

}

 <ui.customView.CenteredToolbar
                android:id="@+id/apd_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:navigationIcon="@drawable/ic_search"
                app:title="Check Title"
                app:elevation="4dp"/>

Upvotes: 3

Shatazone
Shatazone

Reputation: 2512

public void centerTitleAndSubtitle(Toolbar toolbar){
    // Save current title and subtitle
    final CharSequence originalTitle = toolbar.getTitle();
    final CharSequence originalSubtitle = toolbar.getSubtitle();

    // Temporarily modify title and subtitle to help detecting each
    toolbar.setTitle("title");
    toolbar.setSubtitle("subtitle");

    for(int i = 0; i < toolbar.getChildCount(); i++){
        View view = toolbar.getChildAt(i);

        if(view instanceof TextView){
            TextView textView = (TextView) view;


            if(textView.getText().equals("title")){
                // Customize title's TextView
                Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT);
                params.gravity = Gravity.CENTER_HORIZONTAL;
                textView.setLayoutParams(params);

            } else if(textView.getText().equals("subtitle")){
                // Customize subtitle's TextView
                Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT);
                params.gravity = Gravity.CENTER_HORIZONTAL;
                textView.setLayoutParams(params);
            }
        }

        // Restore title and subtitle
        toolbar.setTitle(originalTitle);
        toolbar.setSubtitle(originalSubtitle);
    }
}

If you also want a custom font, check out my other answer here: https://stackoverflow.com/a/35723158/445548

Upvotes: 1

kooldeji
kooldeji

Reputation: 59

The best solution will be to use a nested TextView in the ToolBar then set the layout_width and layout_height to wrap_content. Then set the layout_gravity to center. This way it is not offset by other icons in the toolbar.

Upvotes: 1

LiuWenbin_NO.
LiuWenbin_NO.

Reputation: 1326

The final UI looks like: enter image description here For my project, I have navigation icon at left and menus (more than 1) at right, and want to put the Title at center.

I have setSupportActionBar(toolbar), and _actionBar.setCustomView(R.layout.actionbar_filter);. My layout file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/lib_action_bar_filter_view_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/selectableItemBackgroundBorderless"
                android:gravity="center">

    <TextView
        android:id="@id/lib_action_bar_filter_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:maxLines="2"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:textColor="@android:color/white"
        android:textSize="15sp"/>

</RelativeLayout>

My toolbar extends android.support.v7.widget.Toolbar, then (kind of hard code) measure the size of the RelativeLayout, finally layout it at horizental center.

/**
 * Customized the <code>RelativeLayout</code> inside the <code>Toolbar</code>.
 * Because by default the custom view in the <code>Toolbar</code> cannot set
 * width as our expect value. So this class allows setting the width of the
 * <code>RelativeLayout</code> to take up any percentage of the screen width.
 */
public class CenteredToolbar extends Toolbar {

private static final double WIDTH_PERCENTAGE = 0.8;

private TextView titleView;

public CenteredToolbar(Context context) {
    this(context, null);
}

public CenteredToolbar(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, android.support.v7.appcompat.R.attr.toolbarStyle);
}

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View view = this.getChildAt(i);
        if (view instanceof RelativeLayout) {
            int width = getMeasuredWidth();
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            layoutParams.width = (int) (width * WIDTH_PERCENTAGE);
            view.setLayoutParams(layoutParams);
            break;
        }
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View view = this.getChildAt(i);
        if (view instanceof RelativeLayout) {
            forceTitleCenter(view);
            break;
        }
    }
}

/**
 * Centering the layout.
 *
 * @param view The view to be centered
 */
private void forceTitleCenter(View view) {
    int toolbarWidth = getMeasuredWidth();
    int relativeLayoutWidth = view.getMeasuredWidth();
    int newLeft = (int) (toolbarWidth - relativeLayoutWidth) / 2;
    int top = view.getTop();
    int newRight = newLeft + relativeLayoutWidth;
    int bottom = view.getBottom();
    view.layout(newLeft, top, newRight, bottom);
}
}

Attach my toolbar layout. Maybe you don't need this, I am just pasting out here for someone's reference:

<?xml version="1.0" encoding="utf-8"?>
<com.chinalwb.CenteredToolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/vmosolib_toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    app:contentInsetEnd="0dp"
/>

Upvotes: 9

Malik Faisal
Malik Faisal

Reputation: 21

As far as toolbar is a view group so you can create layouts inside it . Follow these steps

1-Create a textview inside your Toolbar 2-make your textview gravity center

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

        <de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/profile_image"
            android:layout_width="44dp"
            android:layout_height="55dp"
            android:src="@drawable/profile"
            app:civ_border_color="@color/secondary_text"
            app:civ_border_width="2dp" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"
            android:gravity="center"
            style="@style/Base.TextAppearance.AppCompat.Widget.ActionBar.Title"
            />


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

Upvotes: 2

ben10
ben10

Reputation: 190

Use custom title (with gravity center) inside toolbar

     <android.support.v7.widget.Toolbar           
         android:layout_width="match_parent"
         android:layout_height="?attr/actionBarSize"
         android:animateLayoutChanges="true"
         android:backgroundTint="@color/colorPrimary"
         android:background="?attr/colorPrimary"
         android:elevation="4dp"
         android:minHeight="?android:attr/actionBarSize"
         app:layout_collapseMode="pin"
         app:layout_scrollFlags="scroll|exitUntilCollapsed"
         app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
         app:popupTheme="@style/AppTheme.PopupOverlay"
         app:titleTextAppearance="@style/Toolbar.TitleText" >

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

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

Upvotes: 1

Younes
Younes

Reputation: 46

you can insert this code to your code

SupportActionBar.Title = "title";

Upvotes: -7

tompadre
tompadre

Reputation: 807

You can force the toolbar to the center by wrapping title and level right padding which has default left padding for title. Then put background color to the parent of toolbar and that way part which is cut out by wrapping title is in the same color(white in my example):

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white">

            <android.support.v7.widget.Toolbar
               android:id="@+id/toolbar"
               android:layout_width="wrap_content"
               android:layout_height="56dp"
               android:layout_gravity="center_horizontal"
               android:paddingEnd="15dp"
               android:paddingRight="15dp"
               android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
               app:titleTextColor="@color/black"/>

</android.support.design.widget.AppBarLayout>

Upvotes: 11

user2137020
user2137020

Reputation: 606

Just putting another TextView inside Toolbar is not enough to get title centered relative to the screen, its position will be dependent on other items in a toolbar (back button, menu items).

To make title centred you can manually set its position:

Extend android.support.v7.widget.Toolbar class and make following changes:

  1. add TextView
  2. override onLayout() and set TextView location to centre it (titleView.setX((getWidth() - titleView.getWidth())/2))
  3. override setTitle() where set title text to new text view
    public class CenteredToolbar extends Toolbar {

        private TextView titleView;

        public CenteredToolbar(Context context) {
            this(context, null);
        }

        public CenteredToolbar(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, android.support.v7.appcompat.R.attr.toolbarStyle);
        }

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

            titleView = new TextView(getContext());

            int textAppearanceStyleResId;
            TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                    new int[] { android.support.v7.appcompat.R.attr.titleTextAppearance }, defStyleAttr, 0);
            try {
                textAppearanceStyleResId = a.getResourceId(0, 0);
            } finally {
                a.recycle();
            }
            if (textAppearanceStyleResId > 0) {
                titleView.setTextAppearance(context, textAppearanceStyleResId);
            }

            addView(titleView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            titleView.setX((getWidth() - titleView.getWidth())/2);
        }

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

In layout you can use this class like this:

<com.example.CenteredToolbar 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="?attr/colorPrimary"
    android:elevation="4dp"
    android:theme="@style/ToolbarTheme"/>

Also, to make new title text look like standard title you should apply titleTextAppearance style to new TextView (titleView.setTextAppearance(context, textAppearanceStyleResId)).

Upvotes: 9

jesobremonte
jesobremonte

Reputation: 3396

The problem with simply adding a TextView in the Toolbar aligned center is adding menu items in the toolbar which will offset the centered text.

To get around this, I've layered the text on top of the Toolbar, not inside it. This way it doesn't matter how many icons you add, it will not offset the centered text:

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
        </android.support.v7.widget.Toolbar>

        <TextView
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"/>

    </RelativeLayout>
</android.support.design.widget.AppBarLayout>

This way there is no need for any extra logic to compensate for the offset spacing of back buttons/overflow menu/search icons etc. on the toolbar, because the centered text is above it, not in it.

Upvotes: 40

JayaSantoshKumar
JayaSantoshKumar

Reputation: 59

I didn't understand you Question Completely .. but i found Solution Like this

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="?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);

Upvotes: 1

Harry Aung
Harry Aung

Reputation: 1632

When you have Home or Up button together with centered title, and the title isn't centered anymore and is moved slightly to the right a bit, set your textview as width=wrap_content and layout_gravity=center

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"/>

Upvotes: 8

Umesh Kumar Saraswat
Umesh Kumar Saraswat

Reputation: 768

ToolBar is a View Group. so To Center Align The text Use

app_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/in.chabu"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"
    app:theme="@style/ToolBarTheme" 
    android:minHeight="?attr/actionBarSize">

     <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/title_activity_sign_up"
        android:layout_gravity="center"
        android:id="@+id/toolbar_title" 
        android:textStyle="bold"
        android:textColor="@android:color/white"/>

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

activity_sign_up

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="in.chabu.activities.SignUpActivity" >

    <include 
        android:id="@+id/tool_bar"
        layout="@layout/app_bar"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tool_bar"
        android:text="@string/hello_world" />

</RelativeLayout>

Avtivity

public class SignUpActivity extends ActionBarActivity {

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

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

        setSupportActionBar(toolbar);

        getSupportActionBar().setDisplayShowTitleEnabled(false);
    }


}

Upvotes: 10

An SO User
An SO User

Reputation: 24998

Remember that Toolbar is just a ViewGroup like the others. So you can stuff Views into it. In your case, you need a TextView inside a Toolbar.

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Some Fancy Title"
        android:gravity = "center"
        android:id="@+id/toolbar_title" />

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

Now, set the Toolbar as your action bar by first retrieving it and then using the setSupportActionBar().

Since the gravity of the TextView is set to center, the text must be centered.

Upvotes: 35

Related Questions