如何在默认主题(Theme.Holo.Light)中将标题居中对齐于操作栏?

42

我搜寻了很多资料但是找不到方法,如何将ActionBar的标题设置在居中而非左对齐。我使用以下代码将标题设置为居中:

ViewGroup decorView= (ViewGroup) this.getWindow().getDecorView();
LinearLayout root= (LinearLayout) decorView.getChildAt(0);
FrameLayout titleContainer= (FrameLayout) root.getChildAt(0);
TextView title= (TextView) titleContainer.getChildAt(0);
title.setGravity(Gravity.CENTER);

但是它会出现以下错误:
ClassCastException : com.android.internal.widget.ActionBarView can not 
be cast to android.widget.TextView.

如有其他解决方案,任何帮助都将不胜感激。


你是在尝试在Android上模仿iOS的设计吗?因为你真的不应该这样做 :) - REJH
12个回答

127

您可以创建自定义布局并将其应用于操作栏。

为此,请按照以下两个简单步骤进行:

  1. Java代码

    getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
    getSupportActionBar().setCustomView(R.layout.actionbar);
    

其中R.layout.actionbar是以下布局。

  1. 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="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:id="@+id/action_bar_title"
    android:text="YOUR ACTIVITY TITLE"
    android:textColor="#ffffff"
    android:textSize="24sp" />
</LinearLayout>

无论你希望它多复杂,都可以试一试!

编辑:

要设置背景,您可以在容器布局(例如LinearLayout)中使用属性android:background。您可能需要将布局高度android:layout_height设置为match_parent而不是wrap_content

此外,您还可以向其添加LOGO / ICON。为此,请在您的布局中添加一个ImageView,并将布局方向属性android:orientation设置为水平(或者使用RelativeLayout并自己管理它)。

要动态更改上面自定义操作栏的标题,请执行以下操作:

TextView title=(TextView)findViewById(getResources().getIdentifier("action_bar_title", "id", getPackageName()));
title.setText("Your Text Here");

你的第二个答案不起作用了..它说FrameLayout无法解析为类型。 - Ponting
1
它的功能完美,但它使用了自定义显示。而我正在使用Theme.Holo.Light。因此,所有带有图像的标志、背景颜色和返回按钮都被删除,只有一个简单的白色标题栏显示在ActionBar的中心位置。 - Ponting
@StefanoMunarini:我可以从Activity设置textView的文本(标题)吗? - Ponting
不错的技巧,谢谢!但是这里有一个小问题。当应用程序启动时,它会显示带有标题文本的操作栏在左侧,但是“actionbar.xml”只有在几秒钟后才会应用,这不太好。有没有办法解决这个问题?谢谢! - Edmond Tamas
2
如果您正在使用支持ActionBar,请务必使用getSupportActionBar().setDisplayOptions(android.support.v7.app.ActionBar.DISPLAY_SHOW_CUSTOM);。如果仅使用ActionBar.DISPLAY_SHOW_CUSTOM可能会导致编译错误。 - Azurespot
显示剩余14条评论

8

看起来没有办法在不使用自定义视图的情况下完成此操作。您可以获取标题视图:

View decor = getWindow().getDecorView();
TextView title = (TextView) decor.findViewById(getResources().getIdentifier("action_bar_title", "id", "android"));

但是改变gravitylayout_gravity没有效果。 问题在于ActionBarView,它自己布局其子视图,所以改变其子视图的布局参数也没有效果。 要查看此内容,请执行以下代码:
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);

空指针异常,ActionBar的问题。 AppTheme是DarkActionBar。 - narancs

7

在 Lollipop 更新中,支持库类中新增了工具栏。您可以通过在布局中添加工具栏来设计操作栏。

请在应用程序主题中添加以下项目:

 <item name="android:windowNoTitle">true</item>
 <item name="windowActionBar">false</item>

在布局中创建你的工具栏,并将你的TextView包含在中心设计中,设计你的工具栏。
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/acbarcolor">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="@string/app_name"
            android:textColor="#ffffff"
            android:textStyle="bold" />

    </RelativeLayout>

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

将您的操作栏添加为工具栏

toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

请确保您需要像这样在资源文件中包含工具栏:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    android:orientation="vertical"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <include
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        layout="@layout/toolbar" />

    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- Framelayout to display Fragments -->
        <FrameLayout
            android:id="@+id/frame_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <include
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                layout="@layout/homepageinc" />

        </FrameLayout>

        <fragment
            android:id="@+id/fragment1"
            android:layout_gravity="start"
            android:name="com.shouldeye.homepages.HomeFragment"
            android:layout_width="250dp"
            android:layout_height="match_parent" />

    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

5

我知道我的回答有点晚,但这仅仅是代码,不需要xml
这是用于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);
}

超级简单实现,极易定制。不错! - Tadreik

4
如果您正在使用工具栏,则只需添加android:layout_gravity="center_horizontal"在工具栏下方,就像这个片段一样。
 <android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay">

        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"    //Important 
            android:textColor="@color/whitecolor"
            android:textSize="20sp"
            android:textStyle="bold" />
    </android.support.v7.widget.Toolbar>

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

1
希望这篇文章能够帮助到使用工具栏的同学们 :) - Darshan Khatri

3

这真的起作用:

 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;

您需要定义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>

1

Java代码: 在onCreate()中写入以下代码:
getSupportActionBar().setDisplayShowCustomEnabled(true); getSupportActionBar().setCustomView(R.layout.action_bar);

对于自定义视图,只需使用FrameLayout即可,非常简单!
android.support.v7.widget.Toolbar是另一个选项。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left|center_vertical"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="@string/app_name"
        android:textColor="@color/black"
        android:id="@+id/textView" />
</FrameLayout>

1
我认为通过在操作栏上定位视图,您将达到所需的效果。在操作栏的布局中,当布局参数设置为匹配父级时,它并不完全匹配宽度,这就是我在程序中成功实现的原因。通过设置宽度(它的作用类似于layout_weight="value"),我们可以将视图放置在任何我们想要的位置:
    actionBar = getSupportActionBar(); 
    actionBar.setDisplayShowCustomEnabled(true); 

    LayoutInflater ll = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    LinearLayout linearLayout = (LinearLayout) ll.inflate(R.layout.custom_actionbar, null);
    //inner layout within above linear layout
    LinearLayout inner = (LinearLayout) linearLayout.findViewById(R.id.inner_linear_ractionbar);
    inner.setMinimumWidth(getWidth() * 2 / 10);
    // we will set our textview to center and display there some text
    TextView t = (TextView) linearLayout.findViewById(R.id.center_text);
    t.setWidth(getWidth() * 6 / 10);


    Button b = (Button) linearLayout.findViewById(R.id.edit_button);
    b.setWidth(getWidth() *3/ 20);

    ImageButton imageButton = (ImageButton) linearLayout.findViewById(R.id.action_bar_delete_item);
    imageButton.setMinimumWidth(deviceUtils.getWidth() / 20);

这里是getWidth()方法:

 public int getWidth() { 
    DisplayMetrics dm = new DisplayMetrics();
     mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);
    return dm.widthPixels; 
   }

0

解决方案基于以下内容:

  • 您需要使用自己的类来扩展Toolbar(support.v7.widget.toolbar)
  • 您需要覆盖一个方法Toolbar#addView

它是做什么的:

当工具栏第一次执行#setTitle时,它会创建AppCompatTextView并使用它来显示标题文本。

当创建AppCompatTextView时,工具栏(作为ViewGroup)使用#addView方法将其添加到自己的层次结构中。

此外,在尝试找到解决方案时,我注意到textview的布局宽度设置为“wrap_content”,因此我决定将其设置为“match_parent”并将文本对齐方式设置为“center”。

MyToolbar.kt,跳过不相关的内容(构造函数/导入):

class MyToolbar : Toolbar {

  override fun addView(child: View, params: ViewGroup.LayoutParams) {
    if (child is TextView) {
        params.width = ViewGroup.LayoutParams.MATCH_PARENT
        child.textAlignment= View.TEXT_ALIGNMENT_CENTER
    }
    super.addView(child, params)
  }
}

可能会有“副作用” - 这也适用于“字幕”


0

我曾经遇到过同样的问题,由于工具栏自动添加了“主页”按钮,我的文本输入并不完全准确。

我用了一种比较麻烦的方法解决了这个问题,但在我的情况下它很有效。我只是在我的TextView右侧添加了一个边距来补偿左侧的主页按钮。以下是我的工具栏布局:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:elevation="1dp"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:layout_collapseMode="pin"
    android:gravity="center"
    android:background="@color/mainBackgroundColor"
    android:fitsSystemWindows="true" >

    <com.lunabee.common.utils.LunabeeShadowTextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginRight="?attr/actionBarSize"
        android:gravity="center"
        style="@style/navigation.toolbar.title" />

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接