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
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"/>
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
}
}
The final UI looks like: 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"
/>
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
Remember that Toolbar
is just a ViewGroup
like the others. So you can stuff View
s 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.
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:
TextView
onLayout()
and set TextView
location to centre it (titleView.setX((getWidth() - titleView.getWidth())/2)
)setTitle()
where set title text to new text viewpublic 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)
).