如何在Android中使ActionBar标题居中对齐?

109

我试图使用以下代码将文本居中显示在ActionBar中,但它会左对齐。

如何使其居中显示?

ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle("Canteen Home");
actionBar.setHomeButtonEnabled(true);
actionBar.setIcon(R.drawable.back);

1
这是一个非常老的问题。然而,我下面看到的唯一解决方案是创建自定义操作栏。所以这里提供了不创建自定义操作栏的解决方案。http://stackoverflow.com/a/42465266/3866010 希望能帮助到某些人。 - ᴛʜᴇᴘᴀᴛᴇʟ
3
在我提出这个问题将近8年之后,现在再次使用答案 :D - Sourabh Saldi
18个回答

3

最好最简单的方法,特别是对于那些只想要带有重力中心的文本视图而不需要任何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);

检查你的应用主题! - turbandroid

2
您需要设置ActionBar.LayoutParams.WRAP_CONTENTActionBar.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 );

"I'm set ActionBar.LayoutParams..." - 这没有意义。另外,请格式化您的代码。 - sashoalm
哈哈,请不要打曲连强,他的 setDisplayOptions 示例帮助我添加了居中标题和显示主页按钮。 - djdance
“R.layout.action_bar_title”是什么?我找不到它。 - Jose Manuel Abarca Rodríguez
什么是“R.layout.action_bar_title”?请给出解释。我需要在manifests.xml中注册自定义的xml吗? - Ajay Kulkarni

2
这里提供一个完整的 Kotlin + androidx 解决方案,基于 @Stanislas Heili 的回答。希望对其他人有用。这适用于在活动中托管多个片段的情况,同时只有一个片段处于活动状态。
在您的活动中:
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)
}

在你的片段中:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    activity?.title = "some title for fragment"
}

0
对于 Kotlin 用户:
在您的 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))

XML/资源布局如下:

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

0
我看过的其他教程都是覆盖整个操作栏布局来隐藏菜单项。我只需按照以下步骤进行操作即可:
创建一个如下所示的 XML 文件:
<?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>

在类中这样做:

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

这个不起作用 - 可能是因为我显示了导航菜单按钮? - Someone Somewhere

0
我的解决方案是将工具栏的文本部分单独保留,定义样式并指定居中或其他对齐方式。这可以在XML中完成。当有始终可见的操作时,可以在进行计算后指定一些填充。我已经将两个属性从工具栏移动到其子TextView中。可以为这个textView提供id以便从片段中访问。
    <?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>

0

这里有一个快速的提示来居中对齐操作:

android:label=" YourTitle"

假设您启用了Actionbar,您可以在活动中添加此代码,并留出一些空间(可调整)以将标题放置在中心位置。

然而,这只是一个不太可靠的方法。您最好创建一个自定义ActionBar。因此,您需要删除默认的ActionBar并使用此代码替换它作为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>

我使用了 Constraint Layout 来居中 TextView,并使用了 10dp 的高度和 56dp 的高度,使其看起来与默认的 ActionBar 相同。


找了好久终于找到了,太棒了! - Anderson Spencer

-1

这段代码不会隐藏返回按钮,同时将标题居中对齐。

在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);
    }
}

java.lang.NullPointerException ;) 空指针异常 ;) - User

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