【Android】可折叠式标题栏
在 Android 应用开发中,精美的用户界面可以显著提升应用品质和用户体验。Material Design 组件中的 CollapsingToolbarLayout 能够为应用添加动态、流畅的折叠效果,让标题栏不再是静态的元素。本文将深入探讨如何使用 CollapsingToolbarLayout 创建令人惊艳的可折叠标题栏效果。
一、什么是 CollapsingToolbarLayout?
CollapsingToolbarLayout 是 Android Material Design 库中的一个专用布局容器,它扩展了普通 Toolbar 的功能,允许标题栏在用户滚动内容时产生丰富的折叠动画效果。这种效果常见于许多现代 Android 应用,如新闻详情页、商品展示页等场景,能够提供更加沉浸式的用户体验。
二、使用步骤
环境配置
在开始之前,请确保你的项目中已添加 Material Design 依赖:
dependencies {implementation 'com.google.android.material:material:1.8.0'// 其他依赖...
}
基础布局结构
要正确使用 CollapsingToolbarLayout,必须遵循特定的布局层级结构:
<androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns: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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"><com.google.android.material.appbar.AppBarLayoutandroid:id="@+id/appBar"android:layout_width="match_parent"android:layout_height="250dp"android:fitsSystemWindows="true"><com.google.android.material.appbar.CollapsingToolbarLayoutandroid:id="@+id/collapsing_toolbar"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"app:contentScrim="?attr/colorPrimary"app:expandedTitleMarginStart="64dp"app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"><!-- 这里放置标题栏内容 --></com.google.android.material.appbar.CollapsingToolbarLayout></com.google.android.material.appbar.AppBarLayout><!-- 可滚动内容区域 --><androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"><!-- 你的滚动内容 --></androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
层级关系说明:
- CoordinatorLayout 是根容器,负责协调子视图的交互行为
- AppBarLayout 必须是 CoordinatorLayout 的直接子布局
- CollapsingToolbarLayout 必须作为 AppBarLayout 的直接子布局
- 可滚动内容(如 NestedScrollView、RecyclerView)需要设置 app:layout_behavior="@string/appbar_scrolling_view_behavior"
关键属性详解
layout_scrollFlags
控制 CollapsingToolbarLayout 的滚动行为,常用值组合:
- scroll:允许布局随滚动事件滚动(必须包含)
- exitUntilCollapsed:布局折叠完成后保留在界面上,不再移出屏幕
- enterAlways:任何向下滚动操作都会使布局展开
- enterAlwaysCollapsed:类似 enterAlways,但布局以折叠状态开始展开
- snap:滚动结束时,布局会自动折叠或展开到最接近的状态
示例:app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
contentScrim
指定 CollapsingToolbarLayout 在折叠状态及折叠后的背景色,通常设置为应用的主题色:
app:contentScrim="?attr/colorPrimary"
标题相关属性
- app:title:设置标题文本
- app:expandedTitleTextAppearance:展开状态下的标题文字样式
- app:collapsedTitleTextAppearance:折叠状态下的标题文字样式
- app:expandedTitleMargin:展开状态下标题的边距
定义标题栏内容
在 CollapsingToolbarLayout 中,我们可以添加多种视图组件来创建丰富的视觉效果:
<com.google.android.material.appbar.CollapsingToolbarLayout...><!-- 背景图片 --><ImageViewandroid:id="@+id/backdrop"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="centerCrop"android:src="@drawable/header_image"android:contentDescription="@string/header_image_desc"app:layout_collapseMode="parallax"app:layout_collapseParallaxMultiplier="0.7"/><!-- 工具栏 --><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"app:layout_collapseMode="pin"app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/><!-- 其他元素,如浮动按钮 --><com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="@dimen/fab_margin"android:src="@drawable/ic_favorite"app:layout_anchor="@id/appBar"app:layout_anchorGravity="bottom|end"app:backgroundTint="?attr/colorPrimary"app:layout_collapseMode="pin"/></com.google.android.material.appbar.CollapsingToolbarLayout>
layout_collapseMode 属性详解
- pin:在折叠过程中元素位置始终保持不变,适合用于工具栏和重要操作按钮
- parallax:元素在折叠过程中会产生视觉差偏移效果,增强视觉层次感
- 对于 parallax 模式,可以使用 layout_collapseParallaxMultiplier 属性控制视差效果的程度(0.0-1.0)
沉浸式状态栏实现
为了实现背景图片延伸到状态栏的沉浸式效果,需要完成以下步骤:
步骤一:设置 fitsSystemWindows
将需要延伸到状态栏的控件及其所有父布局的 android:fitsSystemWindows 属性设为 true
步骤二:设置透明状态栏主题
在 values/styles.xml 和 values-v21/styles.xml 中定义透明状态栏主题:
values/styles.xml
<resources><style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar"><item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@color/colorPrimaryDark</item><item name="colorAccent">@color/colorAccent</item></style>
</resources>
values-v21/styles.xml
<resources><style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar"><item name="colorPrimary">@color/colorPrimary</item><item name="colorPrimaryDark">@android:color/transparent</item><item name="colorAccent">@color/colorAccent</item><item name="android:statusBarColor">@android:color/transparent</item><item name="android:windowLightStatusBar">true</item></style>
</resources>
三、完整示例代码
以下是一个完整的可折叠标题栏实现示例:
<androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns: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.AppBarLayoutandroid:id="@+id/app_bar"android:layout_width="match_parent"android:layout_height="@dimen/appbar_height"android:fitsSystemWindows="true"><com.google.android.material.appbar.CollapsingToolbarLayoutandroid:id="@+id/collapsing_toolbar"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"app:contentScrim="?attr/colorPrimary"app:expandedTitleMarginEnd="64dp"app:expandedTitleMarginStart="48dp"app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"app:statusBarScrim="@android:color/transparent"><ImageViewandroid:id="@+id/backdrop"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="centerCrop"app:layout_collapseMode="parallax"app:layout_collapseParallaxMultiplier="0.7" /><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"app:layout_collapseMode="pin"app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /></com.google.android.material.appbar.CollapsingToolbarLayout></com.google.android.material.appbar.AppBarLayout><androidx.core.widget.NestedScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/lorem_ipsum"android:textSize="16sp" /></LinearLayout></androidx.core.widget.NestedScrollView><com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="16dp"android:src="@drawable/ic_share"app:layout_anchor="@id/app_bar"app:layout_anchorGravity="bottom|end" /></androidx.coordinatorlayout.widget.CoordinatorLayout>