如何在 Android 中居中对齐 ActionBar 标题?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12387345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to center align the ActionBar title in Android?
提问by Sourabh Saldi
I am trying to use the following code to center the text in the ActionBar
, but it aligns itself to the left.
我正在尝试使用以下代码将 中的文本居中ActionBar
,但它会向左对齐。
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);
回答by Ahmad
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:
要在 ABS 中有一个居中的标题(如果你想在 default 中有这个ActionBar
,只需删除方法名称中的“支持”),你可以这样做:
In your Activity, in your onCreate()
method:
在您的活动中,在您的onCreate()
方法中:
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(R.layout.abs_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">
<android.support.v7.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"
).
现在你应该有一个Actionbar
只有标题的。如果要设置自定义背景,请在上面的 Layout 中进行设置(但不要忘记设置android:layout_height="match_parent"
)。
or with:
或与:
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.yourimage));
回答by Someone Somewhere
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")
我在其他答案上没有取得太大成功......下面正是使用支持库 v7 中的 ActionBar 在 Android 4.4.3 上对我有用的内容。我已将其设置为显示导航抽屉图标(“汉堡菜单按钮”)
XML
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);
回答by ypresto
Define your own custom view with title text, then pass LayoutParams to setCustomView(), as Sergii says.
正如 Sergii 所说,使用标题文本定义您自己的自定义视图,然后将 LayoutParams 传递给 setCustomView()。
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.
编辑:至少对于宽度,您应该使用 WRAP_CONTENT 或您的导航抽屉、应用程序图标等。不会显示(自定义视图显示在操作栏上的其他视图之上)。尤其是在未显示操作按钮时会发生这种情况。
EDITED: Equivalent in xml layout:
编辑:等效于 xml 布局:
<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.
这不需要指定 LayoutParams。
actionBar.setCustomView(getLayoutInflater().inflate(R.layout.action_bar_home, null);
回答by Jordy
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 afteryou assign a custom view:
只是对艾哈迈德回答的快速补充。使用带有 TextView 的自定义视图时,您不能再使用 getSupportActionBar().setTitle。因此,在您分配自定义视图后,在您的 onCreate() 方法中使用此自定义 ActionBar(使用此 xml)设置多个活动时设置标题:
TextView textViewTitle = (TextView) findViewById(R.id.mytext);
textViewTitle.setText(R.string.title_for_this_activity);
回答by Justin Case
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.
好的。经过大量研究,结合上面接受的答案,我提出了一个解决方案,如果您的操作栏中有其他内容(后退/主页按钮,菜单按钮),该解决方案也有效。所以基本上我已经将覆盖方法放在一个基本活动中(所有其他活动都扩展了它),并将代码放在那里。此代码设置每个活动的标题,因为它在 AndroidManifest.xml 中提供,并且还执行其他一些自定义内容(例如在操作栏按钮上设置自定义色调,以及在标题上设置自定义字体)。您只需要在 action_bar.xml 中忽略重力,并使用填充来代替。actionBar != null
使用检查,因为并非我所有的活动都有一个。
Tested on 4.4.2 and 5.0.1
在 4.4.2 和 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):
而我的 action_bar.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: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:
编辑:如果您需要在加载活动后将标题更改为其他内容(已调用 onCreateOptionsMenu),请将另一个 TextView 放入 action_bar.xml 并使用以下代码“填充”此新 TextView,设置文本并显示它:
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):
编辑(25.08.2016):如果您的活动有“后退按钮”,这不适用于 appcompat 24.2.0 修订版(2016 年 8 月)。我提交了一个错误报告(问题 220899),但我不知道它是否有任何用处(怀疑它会很快被修复)。同时解决方案是检查孩子的类是否等于 AppCompatImageButton.class 并执行相同的操作,仅将宽度增加 30%(例如 appCompatImageButton.getWidth()*1.3 在从原始填充中减去此值之前):
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;
}
}
回答by Dinithe Pieris
without customview its able to center actionbar title. its perfectly working for navigation drawer as well
没有 customview 它能够将操作栏标题居中。它也非常适合导航抽屉
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");
Happy coding. thank you.
快乐编码。谢谢你。
回答by Roshan Ramtel
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. :
您必须根据您的要求定义 custom_actionbar.xml 布局,例如:
<?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>
回答by Vlad
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:
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>
回答by u3949141
You need to set ActionBar.LayoutParams.WRAP_CONTENT
and ActionBar.DISPLAY_HOME_AS_UP
你需要设置ActionBar.LayoutParams.WRAP_CONTENT
和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 );
回答by turbandroid
Best and easiest way, specifically for those who just want text view with gravity center without any xml layout.
最好和最简单的方法,特别适合那些只想要重心文本视图而没有任何 xml 布局的人。
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);