iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

Top app bar 提供與當前螢幕相關的內容和操作,通常是與裝置的寬度相同。

將APP的主題使用NoActionBar,如<style name="Theme.MDCSubject" parent="Theme.Material3.Light.NoActionBar">
https://ithelp.ithome.com.tw/upload/images/20220921/201444698C0uLblJH2.png

開始前先介紹 Material 2(M2) 和 Material 3 (M3) 差別

https://ithelp.ithome.com.tw/upload/images/20220921/20144469isy3U1O8t9.png
M2:使用對比色將Top app bar 與下面的內容分開。
M3:可以使用一致顏色將Status Bar、Top app bar 與下面的內容分開。

M3 新增內容

  • 顏色:新的顏色對映和與動態顏色的相容性
  • 陰影效果:沒有陰影,而是顏色填充與內容分離
  • 型別:現在有四種類型的Top app Bar :center-aligned、 small、 medium、 large
  • 排版:預設文字使用Top app Bar類型中的Large
  • Layout:預設高度使用Top app Bar類型中的Large

M3 四種類型

https://ithelp.ithome.com.tw/upload/images/20220921/20144469tJkV7HADeS.png

  1. Center-aligned:用於顯示應用程式名稱或頁面標題。
  2. Small:需要返回鍵和多個操作的子頁面。
  3. Medium:需要返回鍵和用於顯示更大的標題。
  4. Large:用於強調頁面的標題。

實作上探討

op app bars APIs and source code:

基本使用設定

Center-aligned top app bar

https://ithelp.ithome.com.tw/upload/images/20220921/20144469j5ql8bqUgM.png

  1. Center-aligned top app bar : 新增AppBarLayout,background color 預設?attr/colorSurface
  2. page title:在MaterialToolbar新增app:title="" 、設定置中app:titleCentered="true",如果有副標題可以使用app:subtitleCentered="true"
  3. navigation icon :在MaterialToolbar新增app:navigationIcon=""
  4. one actions:在MaterialToolbar新增app:menu=""
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/topAppBar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:title="@string/page_title"
            app:menu="@menu/top_app_bar"
            app:navigationIcon="@drawable/ic_close_24dp"
			app:titleCentered="true" />

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

    <!-- Note: A RecyclerView can also be used -->
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!-- Scrollable content -->

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

新增 menu/top_app_bar.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/icon"
        android:title="@string/icon"
        android:contentDescription="@string/content_description_search"
        app:showAsAction="ifRoom" />

</menu>

Small top app bar

https://ithelp.ithome.com.tw/upload/images/20220921/20144469hiVWUhUoIQ.png

  1. Small top app bar: 新增AppBarLayout
  2. page title:在MaterialToolbar新增app:title=""
  3. navigation icon:在MaterialToolbar新增app:navigationIcon=""
  4. two actions + an overflow menu :在MaterialToolbar新增app:menu=""
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/topAppBar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:title="@string/page_title"
            app:menu="@menu/top_app_bar"
            app:navigationIcon="@drawable/ic_close_24dp" />

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

    <!-- Note: A RecyclerView can also be used -->
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!-- Scrollable content -->

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

menu/top_app_bar.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/edit"
        android:title="@string/edit"
        android:contentDescription="@string/content_description_search"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/favorite"
        android:icon="@drawable/ic_favorite_24dp"
        android:title="@string/favorite"
        android:contentDescription="@string/content_description_favorite"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/more"
        android:title="@string/more"
        android:contentDescription="@string/content_description_more"
        app:showAsAction="never" />

</menu>

程式碼:
navigation icon 點擊監聽 setNavigationOnClickListener
actions icon 也就是MenuItem 點擊監聽 setOnMenuItemClickListener

topAppBar.setNavigationOnClickListener {
    // Handle navigation icon press
}

topAppBar.setOnMenuItemClickListener { menuItem ->
    when (menuItem.itemId) {
        R.id.edit -> {
            // Handle edit text press
            true
        }
        R.id.favorite -> {
            // Handle favorite icon press
            true
        }
        R.id.more -> {
            // Handle more item (inside overflow menu) press
            true
        }
        else -> false
    }
}

Medium top app bar

https://ithelp.ithome.com.tw/upload/images/20220921/20144469YNzqroAWgb.png

  1. Medium collapsing top app bar : 新增CollapsingToolbarLayout 和指定 style="?attr/collapsingToolbarLayoutMediumStyle"
  2. page title:在MaterialToolbar新增app:title=""
  3. navigation icon:在MaterialToolbar新增app:navigationIcon=""
  4. an action icon + an overflow menu:在MaterialToolbar新增app:menu=""
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...>

    <com.google.android.material.appbar.AppBarLayout
        ...
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            style="?attr/collapsingToolbarLayoutMediumStyle"
            android:layout_width="match_parent"
            android:layout_height="?attr/collapsingToolbarLayoutMediumSize">

            <com.google.android.material.appbar.MaterialToolbar
                ...
                android:elevation="0dp" />

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

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

    ...

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Large top app bar

https://ithelp.ithome.com.tw/upload/images/20220921/20144469zIoLZYnqMO.png

  1. Large top app bar: 新增CollapsingToolbarLayout 和指定 style="?attr/collapsingToolbarLayoutLargeStyle"

2、3、4 跟 Medium collapsing top app bar 一樣

<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...>

    <com.google.android.material.appbar.AppBarLayout
        ...
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            style="?attr/collapsingToolbarLayoutLargeStyle"
            android:layout_width="match_parent"
            android:layout_height="?attr/collapsingToolbarLayoutLargeSize">

            <com.google.android.material.appbar.MaterialToolbar
                ...
                android:elevation="0dp" />

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

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

    ...

</androidx.coordinatorlayout.widget.CoordinatorLayout>

其他使用設定

1. Status bar and edge-to-edge

xml:AppBarLayout 設定 android:fitsSystemWindows="true” 避免與狀態列重疊。
Theme:指定android:statusBarColor的顏色

<style name="Theme.MCDProject" parent="Theme.Material3.Light.NoActionBar">
		<item name="android:statusBarColor">@color/shrine_pink_100</item>
</style>

2. Applying scrolling behavior to the top app bar

(1).top app bar 固定,下方內容滑動設定app:liftOnScroll="true"

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/shrine_pink_100"
        app:liftOnScroll="true">

        <!-- Center-aligned、Small-->
        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/topAppBar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"

            app:menu="@menu/top_app_bar"
            app:navigationIcon="@drawable/ic_arrow_back"
            app:title="page_title" />

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

    ... <!-- Note: A RecyclerView can also be used -->

</androidx.coordinatorlayout.widget.CoordinatorLayout>

(2). top app bar 在向上滾動時消失,在向下滾動時出現,設定 app:layout_scrollFlags="scroll|enterAlways|snap"

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/shrine_pink_100">

        <!-- Center-aligned、Small-->
        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/topAppBar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways|snap"
            app:menu="@menu/top_app_bar"
            app:navigationIcon="@drawable/ic_arrow_back"
            app:title="page_title" />

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

    ... <!-- Note: A RecyclerView can also be used -->

</androidx.coordinatorlayout.widget.CoordinatorLayout>

3. Adding an image to a collapsing top app bar

https://ithelp.ithome.com.tw/upload/images/20220921/20144469hlV5uJ03vU.png
添加背景顏色運用在 Medium、Large top app bar,在CollapsingToolbarLayout 設定 style

  • Medium top app bar : style="?attr/collapsingToolbarLayoutMediumStyle"

    高度建議用android:layout_height="?attr/collapsingToolbarLayoutMediumSize"

  • Large top app bar : style="?attr/collapsingToolbarLayoutLargeStyle"

    高度建議用android:layout_height="?attr/collapsingToolbarLayoutLargeSize"

<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...
    android:fitsSystemWindows="true">

    <com.google.android.material.appbar.AppBarLayout
        ...
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            style="?attr/collapsingToolbarLayoutLargeStyle"
            android:layout_width="match_parent"
            android:layout_height="?attr/collapsingToolbarLayoutLargeSize">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/media"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"/>

            <com.google.android.material.appbar.MaterialToolbar
                ...
                android:background="@android:color/transparent" />

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

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

    ...

</androidx.coordinatorlayout.widget.CoordinatorLayout>

res/values/themes.xml

<style name="Theme.App" parent="Theme.Material3.*.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>

完成程式碼:

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    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:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            style="?attr/collapsingToolbarLayoutLargeStyle"
            android:layout_width="match_parent"
            android:layout_height="?attr/collapsingToolbarLayoutLargeSize">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                android:src="@drawable/img_background" />

            <com.google.android.material.appbar.MaterialToolbar
                android:id="@+id/topAppBar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/transparent"
                app:menu="@menu/top_app_bar"
                app:navigationIcon="@drawable/ic_arrow_back"
                app:title="page_title"
                app:titleTextColor="@color/white" />

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

    <!-- Note: A RecyclerView can also be used -->
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!-- Scrollable content -->

    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

4. Applying scrolling behavior to a collapsing top app bar

向上滾動時,Medium、Large的Top app bar會轉換為一般的Top app bar,運用在 Medium、Large top app bar

  • 設定scroll滾輪、exitUntilCollapsed折疊後的高度、snap是否折疊收到邊緣內。

    app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"

  • 轉換為一般的Top app bar 時背景顏色 app:contentScrim

  • view 將固定到位 app:layout_collapseMode="pin"
    https://i.imgur.com/u6aoFTS.gif

<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...>

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

        <com.google.android.material.appbar.CollapsingToolbarLayout
            ...
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
            app:contentScrim="?attr/colorPrimary">

            ...

            <com.google.android.material.appbar.MaterialToolbar
                ...
                app:layout_collapseMode="pin"
                />

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

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

    ...

</androidx.coordinatorlayout.widget.CoordinatorLayout>

完整程式碼

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    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:fitsSystemWindows="true">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            style="?attr/collapsingToolbarLayoutLargeStyle"
            android:layout_width="match_parent"
            android:layout_height="?attr/collapsingToolbarLayoutLargeSize"
            app:contentScrim="@color/shrine_pink_100"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                android:src="@drawable/img_background" />

            <com.google.android.material.appbar.MaterialToolbar
                android:id="@+id/topAppBar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/transparent"
                app:layout_collapseMode="pin"
                app:menu="@menu/top_app_bar"
                app:navigationIcon="@drawable/ic_arrow_back"
                app:title="page_title"
                app:titleTextColor="@color/white"/>

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

    <!-- Note: A RecyclerView can also be used -->
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <!-- Scrollable content -->

    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Anatomy

https://ithelp.ithome.com.tw/upload/images/20220921/20144469BOgaMYtJ6b.png

1. Container

https://ithelp.ithome.com.tw/upload/images/20220921/201444699rzD2uRIRE.png

2. Leading navigation icon

新增 Navigation icon 在Top app bars 會預設在左側。
Navigation可以是menu icon、back icon 等。
https://ithelp.ithome.com.tw/upload/images/20220921/20144469USHDetMLOv.png

3. Headline

標題可以描述使用者當前使用的螢幕或使用者當前所在的部分、正在使用的應用程式。
如果標題文字很長,使用Large Top app bars ,並將標題包裝成兩行,盡量不使用small、medium 或 center-aligned Top App Bar。
https://ithelp.ithome.com.tw/upload/images/20220921/201444697s1IwcY5Im.png

4. Trailing interactive icons

在標題後,容器的後端最多可以放置三個互動式 icon。
1、2 可以放需要用到或常用,剩下其他會收到3 overflow menu 選單中。
https://ithelp.ithome.com.tw/upload/images/20220921/20144469o9Bdur97hw.png


Layout

Center-aligned top app bar 預設Padding和尺寸大小

https://ithelp.ithome.com.tw/upload/images/20220921/20144469Zd6qpuypY5.png

Small top app bar 預設Padding和尺寸大小

https://ithelp.ithome.com.tw/upload/images/20220921/20144469w60FhMnIL9.png

Medium top app bar 預設Padding和尺寸大小

https://ithelp.ithome.com.tw/upload/images/20220921/20144469nRQZeqDDmt.png

Large top app bar 預設Padding和尺寸大小

https://ithelp.ithome.com.tw/upload/images/20220921/2014446923lgQ0eBgb.png

參考資料
Material Design 3 Top App Bars
/images/emoticon/emoticon29.gif


上一篇
Day07 使用 M3 的 MaterialCardView
下一篇
Day09 實戰簡易的卡片瀏覽頁面
系列文
Kotlin 實踐 Material Design 懶人包30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言