在新的 material 设计中,工具栏上是否有官方的 API 中心标题,就像流行的 Android 应用程序一样?

Is there an official API for centered title on Toolbar like on popular Android apps, in the new material design?

背景

过去,Google 显示工具栏时标题总是左对齐:

https://material.io/develop/android/components/app-bar-layout/

然而,最近,似乎在它的一些应用程序上,标题是居中的,即使它没有左右对称的内容。示例在 "Messages" app:

"Google News" app 上:

它还更新了 material 指南,here。示例:

有些人喜欢称它为 "material design 2.0",因为它更新了很多东西。

问题

虽然自 Whosebug 被调用以来有很多类似的问题 "ActionBar" (示例 here ),但这里有所不同,因为它应该有支持库(又名 "Android-X") 有办法正确处理它,因为情况已经发生变化,现在 Google 应该支持它,因为它是指南的一部分,也是各种 Android 应用程序的一部分。

我试过的

我尝试在工具栏中添加一个视图,但即使通过为视图着色,您也可以看到它并没有真正自动居中,而且那是在添加更多 action-items 或 up-button 之前:

activity_main.xml

<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"
        tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            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">

            <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="title"
                      android:gravity="center" android:background="#33ff0000"
                      android:id="@+id/titleTextView"/>
        </androidx.appcompat.widget.Toolbar>

    </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

这个解决方案与其他 Whosebug 线程上提出的许多其他解决方案类似,无论周围的行动项目和其他观点的数量。

我还想出了一个更好的解决方法:在每一侧都有一个工具栏,并使 TextView 的边距是两者的最大值。甚至还有一个库,“Toolbar-Center-Title”……但同样,这是一种解决方法。不是我要问的。

问题

现在是否有一种官方方法可以使工具栏上的标题居中,无论有多少操作项,也不管另一边有什么(例如向上按钮)?

如果是这样,如何做到这一点?

注意:同样,我对解决方法不感兴趣。有很多解决方法,我自己可以想到。

TL;DR: 不,目前没有正式的方法可以使标题在工具栏上居中。


我认为没有官方的方法可以做到这一点,至少现在还没有。但是我知道Flutter framework supports it and it's pretty straight forward: you simply need to pass centerTitle: true to the appbar constructor, as described in this answer。您在问题中提到的应用很有可能是用 Flutter 构建的,因为它们都来自 Google.

我认为最接近您预期布局的解决方法是将 TextView 置于工具栏顶部,如图 here:

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
        </android.support.v7.widget.Toolbar>

        <TextView
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"/>

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

但如果官方 Android API 能够像 flutter 一样支持它,那就太好了。也许您想向 Material Components Android Issue Tracker?

发送功能请求

textAlignment="center"怎么样?当 AppCompatTextView 已设置 layout_width="match_parent" 时,RelativeLayout 可以解决问题;例如:

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

    <androidx.appcompat.widget.LinearLayoutCompat
        android:id="@+id/customView"
        android:minHeight="?android:attr/actionBarSize"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:gravity="top">

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

            <!-- Home Button -->
            <include
                layout="@layout/button_home_menu"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="start"/>

            <androidx.appcompat.widget.LinearLayoutCompat
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="8dp">

                <androidx.appcompat.widget.AppCompatTextView
                    android:id="@+id/title"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/app_name"
                    android:textAlignment="center"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:textSize="18sp"
                    android:textStyle="bold"/>

                <androidx.appcompat.widget.AppCompatTextView
                    android:id="@+id/subtitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/app_version"
                    android:textAlignment="center"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    android:textSize="12sp"
                    android:textStyle="bold"/>

            </androidx.appcompat.widget.LinearLayoutCompat>

        </RelativeLayout>

    </androidx.appcompat.widget.LinearLayoutCompat>

</layout>

down-side 是,当显示多个 menu-items 作为操作按钮时 - 或者当显示非常长的字符串作为标题时,标题可能会与它们重叠 - 但是当只显示一个或两个操作按钮时结合适合视觉可用宽度的标题,这工作得很好 - 这是因为菜单配置 ifRoom 将始终适用,因为有空间。否则只能测量工具栏的哪一侧具有最宽的项目容器 - 然后调整另一侧项目容器的宽度。根据可用房间缩放 font-size 也可能是一种选择,以使其动态适应。

没有正式的方法可以做到这一点,但子类化提供了大部分的覆盖范围而无需疯狂的技巧。

https://gist.github.com/bmc08gt/40a151e93969f2633b9b92bca4b31e83

  • app:contentInsetStart="@dimen/margin_64" //64dp
  • app:contentInsetEnd="@dimen/margin_64" // 64dp

工具栏部分

 <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.appbar.MaterialToolbar
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:gravity="center_horizontal"
            app:contentInsetEnd="@dimen/margin_64"
            app:contentInsetStart="@dimen/margin_64">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Create"
                android:gravity="center_horizontal"
                android:textColor="@color/white"
                android:textSize="18sp" />

        </com.google.android.material.appbar.MaterialToolbar>
  </com.google.android.material.appbar.AppBarLayout>