Related
I want to add a button to my navigation drawer menu, like so:
desired result:
I tried achieving this using the actionLayout parameter, but I seem to only be able to use some space on the right, not the entire width:
current result:
The title seems to be occupying the space on the left.
But I want to add a button with full width like in the first picture.
My current code:
...
<item
android:id="#+id/nav_login"
android:title=""
app:actionLayout="#layout/button_login"
app:showAsAction="ifRoom"/>
...
button_login.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#0000ff"
android:text="Login"
android:textColor="#ffffff"
android:layout_height="match_parent" />
Action view in drawers intended to show this "small" addition view on the right of the menu item, so it'll be restricted in size.
You can add desired button as some sort of footer like following:
<android.support.design.widget.NavigationView
android:id="#+id/drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/drawer">
<Button
android:id="#+id/footer_item_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Footer Button 1" />
</android.support.design.widget.NavigationView>
Note that you can put everything you want as a child, if you want some more views - just add LinearLayout there and put all additional views as children of it.
My solution is now using the MaterialDrawer Library.
I just did a quick test and it solves the problem:
Code:
...
Drawer drawer = new DrawerBuilder()
.withActivity(this)
.withToolbar(findViewById(R.id.toolbar))
.addDrawerItems(
new PrimaryDrawerItem().withName("Entry 1"),
new PrimaryDrawerItem().withName("Entry 2"),
new AbstractDrawerItem() {
#Override
public RecyclerView.ViewHolder getViewHolder(View v) {
return new RecyclerView.ViewHolder(v) {
};
}
#Override
public int getType() {
return 0;
}
#Override
public int getLayoutRes() {
return R.layout.button_a;
}
#Override
public Object withSubItems(List subItems) {
return null;
}
#Override
public Object withParent(IItem parent) {
return null;
}
},
new PrimaryDrawerItem().withName("Entry 3")
)
.build();
...
button_a.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_width="match_parent"
android:text="Login"
android:layout_height="50dp"/>
I want to align the action bar title to centre without the help of custom view . I would appreciate any help.
Without using the custom view, modifying only default action bar title
You can align the title to the center when you use ActionBar, but you can use Toolbar to do this.
Toolbar is more useful and easier than ActionBar, you can use this layout to define the center title TextView for you activity:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="40dip">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/app_name" />
</android.support.v7.widget.Toolbar>
And use this code for a back button:
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_toolbar);
Toolbar toolbar = (Toolbar) findViewById(R.id.single_toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
You also need to override onCreateOptionsMenu method for the menu, and you can refer to this project : chrisbanes/cheesesquare.
Ok, You can try this:
<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:textColor="#fff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_gravity="center"
android:text="#string/app_name" />
</android.support.v7.widget.Toolbar>
And remember to add this line in your activity's java code:
getSupportActionBar.setTitle("");
It seems there is no way to do this without custom view. You can get the title view:
View decor = getWindow().getDecorView();
TextView title = (TextView) decor.findViewById(getResources().getIdentifier("action_bar_title", "id", "android"));
But changing of gravity or layout_gravity doesn't have an effect. The problem in the ActionBarView, which layout its children by itself so changing of layout params of its children also doesn't have an effect. To see this excecute following code:
ViewGroup actionBar = (ViewGroup) decor.findViewById(getResources().getIdentifier("action_bar", "id", "android"));
View v = actionBar.getChildAt(0);
ActionBar.LayoutParams p = new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
p.gravity= Gravity.CENTER;
v.setLayoutParams(p);
v.setBackgroundColor(Color.BLACK);
I am wondering how it is possible to get rid of (or change color) titleDivider in Dialog. It is a blue line below dialog title shown on honeycomb+ devices.
I guess this is relevant piece of layout from SDK, but since there is no style attribute I dont know how to style it. If i try with findViewById there is no android.R.id.titleDivider
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:fitsSystemWindows="true">
<TextView android:id="#android:id/title" style="?android:attr/windowTitleStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="#android:dimen/alert_dialog_title_height"
android:paddingLeft="16dip"
android:paddingRight="16dip"
android:gravity="center_vertical|left" />
<View android:id="#+id/titleDivider"
android:layout_width="match_parent"
android:layout_height="2dip"
android:background="#android:color/holo_blue_light" />
<FrameLayout
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:foreground="?android:attr/windowContentOverlay">
<FrameLayout android:id="#android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</LinearLayout>
I have tried to override dialogTitleDecorLayout which is only reference to dialog_title_holo.xml in my theme.xml, but without success. Error is:
error: Error: No resource found that matches the given name: attr
'dialogTitleDecorLayout'.
To get a reference to titleDivider of AlertDialog to change its color:
int divierId = dialog.getContext().getResources()
.getIdentifier("android:id/titleDivider", null, null);
View divider = dialog.findViewById(divierId);
divider.setBackgroundColor(getResources().getColor(R.color.creamcolor));
You need to implement
myDialog = builder.create();
myDialog.setOnShowListener(new OnShowListenerMultiple());
//----------------------------
//Function to change the color of title and divider of AlertDialog
public static class OnShowListenerMultiple implements DialogInterface.OnShowListener {
#Override
public void onShow( DialogInterface dialog ) {
if( !(dialog instanceof Dialog) )
return;
Dialog d = ((Dialog) dialog);
final Resources resources = d.getContext().getResources();
final int color = AppUtility.getColor( resources, R.color.defaultColor );
try {
int titleId = resources.getIdentifier( "android:id/alertTitle", null, null );
TextView titleView = d.findViewById( titleId );
titleView.setTextColor( color );
}
catch( Exception e ) {
Log.e( "XXXXXX", "alertTitle could not change color" );
}
try {
int divierId = resources.getIdentifier( "android:id/titleDivider", null, null );
View divider = d.findViewById( divierId );
divider.setBackgroundColor( color );
}
catch( Exception e ) {
Log.e( "XXXXXX", "titleDivider could not change color" );
}
}
}
I solved the issue by using DialogFragment.STYLE_NO_TITLE theme and then faking title bar in dialog layout.
Here is how I resolved that (thanks to http://joerg-richter.fuyosoft.com/?p=181 ):
MyDialogBuilder.class
public class MyDialogBuilder extends android.app.AlertDialog.Builder {
public MyDialogBuilder(Context context) {
super(context);
}
#NonNull
#Override
public android.app.AlertDialog create() {
final android.app.AlertDialog alertDialog = super.create();
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
int titleDividerId = getContext().getResources()
.getIdentifier("titleDivider", "id", "android");
View titleDivider = alertDialog.findViewById(titleDividerId);
if (titleDivider != null) {
titleDivider.setBackgroundColor(getContext().getResources()
.getColor(R.color.alert_dialog_divider));
}
}
});
return alertDialog;
}
}
use
<View android:id="#+id/titleDivider"
android:layout_width="match_parent"
android:layout_height="2dip"
android:background=#CC3232 />
Before write dialog.show(), write:
int divierId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider", null, null);
View divider = dialog.findViewById(divierId);
if(divider!=null){
divider.setBackgroundColor(getResources().getColor(R.color.transparent));}
In colors.xml:
<color name="transparent">#00000000</color>
If you don't want to use Default style, don't use AlertDialog. You could go with Activity(with your custom layout) with Dialog Theme.
<activity android:theme="#android:style/Theme.Dialog">
This one is tested on some 4.x devices:
TextView title = (TextView)getWindow().getDecorView().findViewById(android.R.id.title);
((ViewGroup)title.getParent()).getChildAt(1).setVisibility(View.GONE);
Your idea was correct. However, dialogTitleDecorLayout you were looking for is a private resource, so you can't access it in a normal way. But you still can access it using * syntax:
<item name="*android:dialogTitleDecorLayout">#layout/dialog_title</item>
Adding this to my own style and simply copying dialog_title.xml to my app and changing it slightly solved the problem in my case.
Do you watchthis and there is a pcecial library for that, you can watch it there. And the last link will solve you problem
you can make a custom dialog like this:
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.custom_dialog);
Button okay = (Button) dialog.findViewById(R.id.button1);
okay.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// do your work
}
});
Set a custom title in layout don't use android
dialog.setTitle();
and your custom_dialog.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android1="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:textSize="40sp"
android:text="Hello"/>
<Button
android:id="#+id/button1"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:text="OK" />
</RelativeLayout>
"Removing the blue line" if I guess correctly means dropping the border between the title of the dialog and it's body. That border come from the Holo theme, so it's not possible to drop it without using your custom layout.
Create a file named custom-dialog.xml with the following content (it's just an example..modify it as you want):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/general_dialog_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/dialogTopImage"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.12"
android:padding="10dp" />
<LinearLayout
android:id="#+id/dialogLine"
android:layout_width="fill_parent"
android:layout_height="3dp"
android:background="#drawable/green_btn"
android:orientation="vertical" />
<TextView
android:id="#+id/dialogText"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.32"
android:padding="5dp"
android:text=""
/>
<LinearLayout
android:id="#+id/general_dialog_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center"
android:layout_marginBottom="5dp"
android:layout_weight="0.11"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/dialogButton"
android:layout_width="100dp"
android:textSize="8pt"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:background="#drawable/green_btn"
android:gravity="center"
android:text="Ok" />
</LinearLayout>
As you see I'm using resources and stuff that won't be in your project, but you can remove them safely. The result in my case is more or less the following one, with an image at top that I'll programatically set in the code.
To create the dialog then use something like:
private Dialog createAndShowCustomDialog(String message, Boolean positive, Drawable d, View.OnClickListener cl, String text1) {
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.general_dialog_layout);
// BIND
ImageView image = (ImageView) dialog.findViewById(R.id.dialogTopImage);
TextView text = (TextView) dialog.findViewById(R.id.dialogText);
Button button = (Button) dialog.findViewById(R.id.dialogButton);
LinearLayout line = (LinearLayout) dialog.findViewById(R.id.dialogLine);
// SET WIDTH AND HEIGHT
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = (int) (displaymetrics.widthPixels * 0.85);
int height = (int) (displaymetrics.heightPixels * 0.60);
WindowManager.LayoutParams params = getWindow().getAttributes();
params.width = width;
dialog.getWindow().setLayout(width, height);
// SET TEXTS
text.setText(message);
button.setText(text1);
// SET IMAGE
if (d == null) {
image.setImageDrawable(getResources().getDrawable(R.drawable.font_error_red));
} else {
image.setImageDrawable(d);
}
// SET ACTION
if (cl == null) {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
} else {
button.setOnClickListener(cl);
}
// SHOW
dialog.show();
return dialog;
}
These is no way hiding it by control brotha.. I've had the same problem. only thing you can do is create your own CustomDialog
Here is a sample App
Download and have look at the design pattern, then it will be easy
Here is one Tutorial About making Custom Dialog
Important part is after creating the DialogObject don't set the Title by setTitle()
create TextView inside your CustomLayout and call it from findViewByID() and set your title
In colors.xml:
<color name="transparent">#00000000</color>
In dialog:
int divierId = dialog.getContext().getResources().getIdentifier("android:id/titleDivider",null, null);
View divider = d.findViewById(divierId);
divider.setBackgroundColor(getResources().getColor(R.color.transparent));
In order to hide the default blue line completely (assuming you're in DialogFragment):
Dialog dialog = getDialog();
if (dialog != null) {
final int dividerId = dialog.getContext().getResources()
.getIdentifier("android:id/titleDivider", null, null);
View divider = dialog.findViewById(dividerId);
if (divider != null) {
divider.setBackground(null);
}
}
I have a requirement to center a custom logo (using an ImageView) in the Actionbar for the "Home" activity. I'm using ABS for this project. This is very similar to a another question posted on S.O. (ActionBar logo centered and Action items on sides), but I'm not sure if the ImageView or search menu makes a difference, as I'm not getting the results I'm looking for (a centered image), or if I've just got it wrong. Basically, I set an Icon on the left, insert the custom view in the center, and have a search icon on the right (OptionsMenu). The image does appear a bit to the right of the icon, but it's still left of centered. Any pointers on how to center an ImageView in the actionbar would be greatly appreciated.
Home.java:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
LayoutInflater inflater = (LayoutInflater) getSupportActionBar().getThemedContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
final View customActionBarView = inflater.inflate(
R.layout.actionbar_custom_view_home, null);
/* Show the custom action bar view and hide the normal Home icon and title */
final ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setIcon(R.drawable.ic_ab_som);
actionBar.setCustomView(customActionBarView);
actionBar.setDisplayShowCustomEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.search, menu);
return true;
}
res/layout/actionbar_custom_view_home.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center">
<ImageView
android:id="#+id/actionBarLogo"
android:contentDescription="#string/application_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:duplicateParentState="false"
android:focusable="false"
android:longClickable="false"
android:padding="#dimen/padding_small"
android:src="#drawable/logo_horizontal" />
</LinearLayout>
res/menu/search.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#id/search_item"
android:icon="?attr/action_search"
android:title="#string/search_label"
android:showAsAction="ifRoom|collapseActionView">
</item>
</menu>
If you want imageview in Center of ActionBar then use:
just replace getActionBar(); to getSupportActionBar(); in below code
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setCustomView(R.layout.actionbar_custom_view_home);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
your actionbar_custom_view_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<ImageView
android:id="#+id/actionBarLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:longClickable="false"
android:src="#drawable/ic_launcher" />
</LinearLayout>
Hide Actionbar Icon
final ActionBar actionBar = getActionBar();
actionBar.setCustomView(R.layout.actionbar_custom_view_home);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
Note: for < 11 API use getSupportActionBar() and > 11 API use getActionBar()
EDITED: 02/03/16 for Toolbar
<android.support.v7.widget.Toolbar
style="#style/ToolBarStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="#dimen/abc_action_bar_default_height_material">
<ImageView
android:layout_width="wrap_content"
android:contentDescription="#string/logo"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/ic_launcher"/>
</android.support.v7.widget.Toolbar>
Explained:
The pink container, is the real space where you will add the view.
The trick is doing some maths, to center the View (whatever) to the middle.
In my case, the View was a TextView. Here's my full method:
public void addTextToActionBar( String textToSet )
{
mActionbar.setDisplayShowCustomEnabled( true );
// Inflate the custom view
LayoutInflater inflater = LayoutInflater.from( this );
View header = inflater.inflate( R.layout.actionbar_header, null );
//Here do whatever you need to do with the view (set text if it's a textview or whatever)
TextView tv = (TextView) header.findViewById( R.id.program_title );
tv.setText( textToSet );
// Magic happens to center it.
int actionBarWidth = DeviceHelper.getDeviceWidth( this ); //Google for this method. Kinda easy.
tv.measure( 0, 0 );
int tvSize = tv.getMeasuredWidth();
try
{
int leftSpace = 0;
View homeButton = findViewById( android.R.id.home );
final ViewGroup holder = (ViewGroup) homeButton.getParent();
View firstChild = holder.getChildAt( 0 );
View secondChild = holder.getChildAt( 1 );
leftSpace = firstChild.getWidth()+secondChild.getWidth();
}
catch ( Exception ignored )
{}
mActionbar.setCustomView( header );
if ( null != header )
{
ActionBar.LayoutParams params = (ActionBar.LayoutParams) header.getLayoutParams();
if ( null != params )
{
int leftMargin = ( actionBarWidth / 2 - ( leftSpace ) ) - ( tvSize / 2 ) ;
params.leftMargin = 0 >= leftMargin ? 0 : leftMargin;
}
}
}
Layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical|center"
android:orientation="horizontal" >
<TextView
android:id="#+id/program_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:contentDescription="#string/content_description_program_title"
android:ellipsize="end"
android:maxLines="1"
android:textSize="22sp"/>
</RelativeLayout>
Enjoy.
I encountered this problem,here is my solution:
ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(
ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.MATCH_PARENT);
layoutParams.gravity = Gravity.CENTER_HORIZONTAL|Gravity.CENTER_HORIZONTAL;
actionBar.setCustomView(yourCustomView,layoutParams);
The ImageView in your code is centered relative to the LinearLayout, not to the Action Bar. You can add left margin (android:layout_marginLeft) to the layout to adjust image position.
Other way to do it is not to add an icon and action items to the Action Bar, but to use a custom layout with icon and buttons inside. But you will need to handle action items yourself in that case.
Late to the party but in case it helps anyone else - use a layer-list and set it as the background. Otherwise, the logo will be centering based on remaining space, not the entire toolbar as Reinherd mentions.
You can use a layer-list with a static background color, and an image with gravity set to center as below. Hope it helps!
toolbar.axml
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#drawable/toolbar_background"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways"
app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
toolbar_background.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimary" />
</shape>
</item>
<item>
<bitmap android:src="#drawable/logo" android:gravity="center" />
</item>
</layer-list>
I'm faced with the same problem and I suggest the following solution:
in your res/layout/actionbar_custom_view_home.xml change width of layout to wrap_content:
android:layout_width="wrap_content"
Get width of action bar like this:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
//width of action bar is the same as width of whole screen
final int actionBarWidth = size.x;
Add layoutListener to your customActionBarView:
customActionBarView.addOnLayoutChangeListener(
new OnLayoutChangeListener() {
#Override
public void onGlobalLayout() {
float x = customActionBarView.getX();
int logoImageWidth = imageLogo.getWidth();
int logoPosition = actionBarWidth / 2 - logoImageWidth / 2;
if (x != logoPosition) {
customActionBarView.setX(logoPosition);
customActionBarView.requestLayout();
} else {
customActionBarView.removeOnLayoutChangeListener(this);
}
}
}
);
The only thing I found working is putting (put right or left as needed, or both):
android:layout_marginLeft|Right="?attr/actionBarSize"
that I found here:
http://sourcey.com/android-custom-centered-actionbar-with-material-design/
For me "layoutParams.leftMargin" did the magic. I am able to push icon from left to right.
androidx.appcompat.app.ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(actionBar.getDisplayOptions()
| ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setDisplayOptions(actionBar.getDisplayOptions());
ImageView imageView = new ImageView(actionBar.getThemedContext());
imageView.setImageResource(R.drawable.content_copy);
ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.WRAP_CONTENT
);
layoutParams.leftMargin = 50;
imageView.setLayoutParams(layoutParams);
actionBar.setCustomView(imageView);
I am trying to use the following code to center the text in the ActionBar, but it aligns itself to the left.
How do you make it appear in the center?
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle("Canteen Home");
actionBar.setHomeButtonEnabled(true);
actionBar.setIcon(R.drawable.back);
To have a centered title in ABS (if you want to have this in the default ActionBar, just remove the "support" in the method names), you could just do this:
In your Activity, in your onCreate() method:
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.abs_layout);
abs_layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvTitle"
style="#style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFFFFF" />
</LinearLayout>
Now you should have an Actionbar with just a title. If you want to set a custom background, set it in the Layout above (but then don't forget to set android:layout_height="match_parent").
or with:
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.yourimage));
I haven't had much success with the other answers... below is exactly what worked for me on Android 4.4.3 using the ActionBar in the support library v7. I have it set up to show the navigation drawer icon ("burger menu button")
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/actionbar_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:clickable="false"
android:focusable="false"
android:longClickable="false"
android:textStyle="bold"
android:textSize="18sp"
android:textColor="#FFFFFF" />
</LinearLayout>
Java
//Customize the ActionBar
final ActionBar abar = getSupportActionBar();
abar.setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar_background));//line under the action bar
View viewActionBar = getLayoutInflater().inflate(R.layout.actionbar_titletext_layout, null);
ActionBar.LayoutParams params = new ActionBar.LayoutParams(//Center the textview in the ActionBar !
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.MATCH_PARENT,
Gravity.CENTER);
TextView textviewTitle = (TextView) viewActionBar.findViewById(R.id.actionbar_textview);
textviewTitle.setText("Test");
abar.setCustomView(viewActionBar, params);
abar.setDisplayShowCustomEnabled(true);
abar.setDisplayShowTitleEnabled(false);
abar.setDisplayHomeAsUpEnabled(true);
abar.setIcon(R.color.transparent);
abar.setHomeButtonEnabled(true);
Define your own custom view with title text, then pass LayoutParams to setCustomView(), as Sergii says.
ActionBar actionBar = getSupportActionBar()
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(getLayoutInflater().inflate(R.layout.action_bar_home, null),
new ActionBar.LayoutParams(
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.MATCH_PARENT,
Gravity.CENTER
)
);
EDITED: At least for width, you should use WRAP_CONTENT or your navigation drawer, app icon, etc. WON'T BE SHOWN (custom view shown on top of other views on action bar). This will occur especially when no action button is shown.
EDITED: Equivalent in xml layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
This doesn't require LayoutParams to be specified.
actionBar.setCustomView(getLayoutInflater().inflate(R.layout.action_bar_home, null);
Just a quick addition to Ahmad's answer. You can't use getSupportActionBar().setTitle anymore when using a custom view with a TextView. So to set the title when you have multiple Activities with this custom ActionBar (using this one xml), in your onCreate() method after you assign a custom view:
TextView textViewTitle = (TextView) findViewById(R.id.mytext);
textViewTitle.setText(R.string.title_for_this_activity);
Code here working for me.
// Activity
public void setTitle(String title){
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
TextView textView = new TextView(this);
textView.setText(title);
textView.setTextSize(20);
textView.setTypeface(null, Typeface.BOLD);
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
textView.setGravity(Gravity.CENTER);
textView.setTextColor(getResources().getColor(R.color.white));
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(textView);
}
// Fragment
public void setTitle(String title){
((AppCompatActivity)getActivity()).getSupportActionBar().setHomeButtonEnabled(true);
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
TextView textView = new TextView(getActivity());
textView.setText(title);
textView.setTextSize(20);
textView.setTypeface(null, Typeface.BOLD);
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
textView.setGravity(Gravity.CENTER);
textView.setTextColor(getResources().getColor(R.color.white));
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
((AppCompatActivity)getActivity()).getSupportActionBar().setCustomView(textView);
}
Without customview its able to center actionbar title.
It's perfectly working for navigation drawer as well
int titleId = getResources().getIdentifier("action_bar_title", "id", "android");
TextView abTitle = (TextView) findViewById(titleId);
abTitle.setTextColor(getResources().getColor(R.color.white));
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
abTitle.setGravity(Gravity.CENTER);
abTitle.setWidth(metrics.widthPixels);
getActionBar().setTitle("I am center now");
OK. After a lot of research, combined with the accepted answer above, I have come up with a solution that also works if you have other stuff in your action bar (back/home button, menu button). So basically I have put the override methods in a basic activity (which all other activities extend), and placed the code there. This code sets the title of each activity as it is provided in AndroidManifest.xml, and also does som other custom stuff (like setting a custom tint on action bar buttons, and custom font on the title). You only need to leave out the gravity in action_bar.xml, and use padding instead. actionBar != null check is used, since not all my activities have one.
Tested on 4.4.2 and 5.0.1
public class BaseActivity extends AppCompatActivity {
private ActionBar actionBar;
private TextView actionBarTitle;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
super.onCreate(savedInstanceState);
...
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setElevation(0);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setCustomView(R.layout.action_bar);
LinearLayout layout = (LinearLayout) actionBar.getCustomView();
actionBarTitle = (TextView) layout.getChildAt(0);
actionBarTitle.setText(this.getTitle());
actionBarTitle.setTypeface(Utility.getSecondaryFont(this));
toolbar = (Toolbar) layout.getParent();
toolbar.setContentInsetsAbsolute(0, 0);
if (this.getClass() == BackButtonActivity.class || this.getClass() == AnotherBackButtonActivity.class) {
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
Drawable wrapDrawable = DrawableCompat.wrap(getResources().getDrawable(R.drawable.ic_back));
DrawableCompat.setTint(wrapDrawable, getResources().getColor(android.R.color.white));
actionBar.setHomeAsUpIndicator(wrapDrawable);
actionBar.setIcon(null);
}
else {
actionBar.setHomeButtonEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setHomeAsUpIndicator(null);
actionBar.setIcon(null);
}
}
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if(menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception ex) {
// Ignore
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (actionBar != null) {
int padding = (getDisplayWidth() - actionBarTitle.getWidth())/2;
MenuInflater inflater = getMenuInflater();
if (this.getClass() == MenuActivity.class) {
inflater.inflate(R.menu.activity_close_menu, menu);
}
else {
inflater.inflate(R.menu.activity_open_menu, menu);
}
MenuItem item = menu.findItem(R.id.main_menu);
Drawable icon = item.getIcon();
icon.mutate().mutate().setColorFilter(getResources().getColor(R.color.white), PorterDuff.Mode.SRC_IN);
item.setIcon(icon);
ImageButton imageButton;
for (int i =0; i < toolbar.getChildCount(); i++) {
if (toolbar.getChildAt(i).getClass() == ImageButton.class) {
imageButton = (ImageButton) toolbar.getChildAt(i);
padding -= imageButton.getWidth();
break;
}
}
actionBarTitle.setPadding(padding, 0, 0, 0);
}
return super.onCreateOptionsMenu(menu);
} ...
And my action_bar.xml is like this (if anyone is interested):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/actionbar_text_color"
android:textAllCaps="true"
android:textSize="9pt"
/>
</LinearLayout>
EDIT: If you need to change the title to something else AFTER the activity is loaded (onCreateOptionsMenu has already been called), put another TextView in your action_bar.xml and use the following code to "pad" this new TextView, set text and show it:
protected void setSubTitle(CharSequence title) {
if (!initActionBarTitle()) return;
if (actionBarSubTitle != null) {
if (title != null || title.length() > 0) {
actionBarSubTitle.setText(title);
setActionBarSubTitlePadding();
}
}
}
private void setActionBarSubTitlePadding() {
if (actionBarSubTitlePaddingSet) return;
ViewTreeObserver vto = layout.getViewTreeObserver();
if(vto.isAlive()){
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int padding = (getDisplayWidth() - actionBarSubTitle.getWidth())/2;
ImageButton imageButton;
for (int i = 0; i < toolbar.getChildCount(); i++) {
if (toolbar.getChildAt(i).getClass() == ImageButton.class) {
imageButton = (ImageButton) toolbar.getChildAt(i);
padding -= imageButton.getWidth();
break;
}
}
actionBarSubTitle.setPadding(padding, 0, 0, 0);
actionBarSubTitlePaddingSet = true;
ViewTreeObserver obs = layout.getViewTreeObserver();
obs.removeOnGlobalLayoutListener(this);
}
});
}
}
protected void hideActionBarTitle() {
if (!initActionBarTitle()) return;
actionBarTitle.setVisibility(View.GONE);
if (actionBarSubTitle != null) {
actionBarSubTitle.setVisibility(View.VISIBLE);
}
}
protected void showActionBarTitle() {
if (!initActionBarTitle()) return;
actionBarTitle.setVisibility(View.VISIBLE);
if (actionBarSubTitle != null) {
actionBarSubTitle.setVisibility(View.GONE);
}
}
EDIT (25.08.2016): This does not work with appcompat 24.2.0 revision (August 2016), if your activity has a "back button". I filed a bug report (Issue 220899), but I do not know if it is of any use (doubt it will be fixed any time soon). Meanwhile the solution is to check if the child's class is equal to AppCompatImageButton.class and do the same, only increase the width by 30% (e.g. appCompatImageButton.getWidth()*1.3 before subtracting this value from the original padding):
padding -= appCompatImageButton.getWidth()*1.3;
In the mean time I threw in some padding/margin checks in there:
Class<?> c;
ImageButton imageButton;
AppCompatImageButton appCompatImageButton;
for (int i = 0; i < toolbar.getChildCount(); i++) {
c = toolbar.getChildAt(i).getClass();
if (c == AppCompatImageButton.class) {
appCompatImageButton = (AppCompatImageButton) toolbar.getChildAt(i);
padding -= appCompatImageButton.getWidth()*1.3;
padding -= appCompatImageButton.getPaddingLeft();
padding -= appCompatImageButton.getPaddingRight();
if (appCompatImageButton.getLayoutParams().getClass() == LinearLayout.LayoutParams.class) {
padding -= ((LinearLayout.LayoutParams) appCompatImageButton.getLayoutParams()).getMarginEnd();
padding -= ((LinearLayout.LayoutParams) appCompatImageButton.getLayoutParams()).getMarginStart();
}
break;
}
else if (c == ImageButton.class) {
imageButton = (ImageButton) toolbar.getChildAt(i);
padding -= imageButton.getWidth();
padding -= imageButton.getPaddingLeft();
padding -= imageButton.getPaddingRight();
if (imageButton.getLayoutParams().getClass() == LinearLayout.LayoutParams.class) {
padding -= ((LinearLayout.LayoutParams) imageButton.getLayoutParams()).getMarginEnd();
padding -= ((LinearLayout.LayoutParams) imageButton.getLayoutParams()).getMarginStart();
}
break;
}
}
It works nicely.
activity = (AppCompatActivity) getActivity();
activity.getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.custom_actionbar, null);
ActionBar.LayoutParams p = new ActionBar.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
Gravity.CENTER);
((TextView) v.findViewById(R.id.title)).setText(FRAGMENT_TITLE);
activity.getSupportActionBar().setCustomView(v, p);
activity.getSupportActionBar().setDisplayShowTitleEnabled(true);
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Below layout of custom_actionbar:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:text="Example"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/colorBlack" />
</RelativeLayout>
Best and easiest way, specifically for those who just want text view with gravity center without any xml layout.
AppCompatTextView mTitleTextView = new AppCompatTextView(getApplicationContext());
mTitleTextView.setSingleLine();
ActionBar.LayoutParams layoutParams = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.CENTER;
actionBar.setCustomView(mTitleTextView, layoutParams);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
mTitleTextView.setText(text);
mTitleTextView.setTextAppearance(getApplicationContext(), android.R.style.TextAppearance_Medium);
A Kotlin-only solution that does not require to have changes in the XML Layouts:
//Function to call in onResume() of your activity
private fun centerToolbarText() {
val mTitleTextView = AppCompatTextView(this)
mTitleTextView.text = title
mTitleTextView.setSingleLine()//Remove it if you want to allow multiple lines in the toolbar
mTitleTextView.textSize = 25f
val layoutParams = android.support.v7.app.ActionBar.LayoutParams(
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.WRAP_CONTENT
)
layoutParams.gravity = Gravity.CENTER
supportActionBar?.setCustomView(mTitleTextView,layoutParams)
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
}
After a lot of research:
This actually works:
getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getActionBar().setCustomView(R.layout.custom_actionbar);
ActionBar.LayoutParams p = new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
p.gravity = Gravity.CENTER;
You have to define custom_actionbar.xml layout which is as per your requirement e.g. :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#2e2e2e"
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/top_banner"
android:layout_gravity="center"
/>
</LinearLayout>
You need to set ActionBar.LayoutParams.WRAP_CONTENT and ActionBar.DISPLAY_HOME_AS_UP
View customView = LayoutInflater.from(this).inflate(R.layout.actionbar_title, null);
ActionBar.LayoutParams params = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP );
Here is a complete Kotlin + androidx solution, building upon the answer from #Stanislas Heili. I hope it may be useful to others. It's for the case when you have an activity that hosts multiple fragments, with only one fragment active at the same time.
In your activity:
private lateinit var customTitle: AppCompatTextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// stuff here
customTitle = createCustomTitleTextView()
// other stuff here
}
private fun createCustomTitleTextView(): AppCompatTextView {
val mTitleTextView = AppCompatTextView(this)
TextViewCompat.setTextAppearance(mTitleTextView, R.style.your_style_or_null);
val layoutParams = ActionBar.LayoutParams(
ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.WRAP_CONTENT
)
layoutParams.gravity = Gravity.CENTER
supportActionBar?.setCustomView(mTitleTextView, layoutParams)
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
return mTitleTextView
}
override fun setTitle(title: CharSequence?) {
customTitle.text = title
}
override fun setTitle(titleId: Int) {
customTitle.text = getString(titleId)
}
In your fragments:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity?.title = "some title for fragment"
}
The other tutorials I've seen override the whole action bar layout hiding the MenuItems. I've got it worked just doing the following steps:
Create a xml file as following:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:ellipsize="end"
android:maxLines="1"
android:text="#string/app_name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/white" />
</RelativeLayout>
And in the classe do it:
LayoutInflater inflator = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflator.inflate(R.layout.action_bar_title, null);
ActionBar.LayoutParams params = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT, Gravity.CENTER);
TextView titleTV = (TextView) v.findViewById(R.id.title);
titleTV.setText("Test");
For Kotlin users:
Use the following code in your activity:
// Set custom action bar
supportActionBar?.displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM
supportActionBar?.setCustomView(R.layout.action_bar)
// Set title for action bar
val title = findViewById<TextView>(R.id.titleTextView)
title.setText(resources.getText(R.string.app_name))
And the XML/ resource layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textColor="#color/black"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
My solution will be to keep text part of tool bar separate, to define style and say, center or whichever alignment. It can be done in XML itself. Some paddings can be specified after doing calculations when you have actions that are visible always. I have moved two attributes from toolbar to its child TextView. This textView can be provided id to be accessed from fragments.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<androidx.appcompat.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:theme="#style/defaultTitleTheme"
app:titleTextColor="#color/white"-->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="#dimen/icon_size"
android:text="#string/title_home"
style="#style/defaultTitleTheme"
tools:ignore="RtlSymmetry" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here's a quick tip to center align the action:
android:label=" YourTitle"
Assuming that you have Actionbar Enable, You can add this in your activity with some space (Can be adjusted) to place the title at the center.
However, This is just diddly and unreliable method. You probably shouldn't do that. So, The best thing to do is to create a custom ActionBar. So, What you wanna do is remove the default Actionbar and use this to replace it as an ActionBar.
<androidx.constraintlayout.widget.ConstraintLayout
android:elevation="30dp"
android:id="#+id/customAction"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/colorOnMain"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textAllCaps="true"
android:textColor="#FFF"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
I have used Constraint Layout to center the textView and used 10dp elevation with 56dp height so that it looks as same as the default ActionBar.
This code will not hide back button, Same time will align the title in centre.
call this method in oncreate
centerActionBarTitle();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
myActionBar.setIcon(new ColorDrawable(Color.TRANSPARENT));
private void centerActionBarTitle() {
int titleId = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
titleId = getResources().getIdentifier("action_bar_title", "id", "android");
} else {
// This is the id is from your app's generated R class when
// ActionBarActivity is used for SupportActionBar
titleId = R.id.action_bar_title;
}
// Final check for non-zero invalid id
if (titleId > 0) {
TextView titleTextView = (TextView) findViewById(titleId);
DisplayMetrics metrics = getResources().getDisplayMetrics();
// Fetch layout parameters of titleTextView
// (LinearLayout.LayoutParams : Info from HierarchyViewer)
LinearLayout.LayoutParams txvPars = (LayoutParams) titleTextView.getLayoutParams();
txvPars.gravity = Gravity.CENTER_HORIZONTAL;
txvPars.width = metrics.widthPixels;
titleTextView.setLayoutParams(txvPars);
titleTextView.setGravity(Gravity.CENTER);
}
}