You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义Toolbar结合AppBarLayout实现折叠标题效果咨询

实现自定义Toolbar的标题折叠移动效果

你要的效果完全可以通过XML结构调整+Material Design组件的原生特性实现,不需要额外的Kotlin滚动监听——你的现有布局存在嵌套错误(AppBarLayout不应嵌套在CollapsingToolbarLayout内部),这是导致效果不达标的核心原因。


方案一:用CollapsingToolbarLayout原生特性实现(推荐,无需代码)

这种方式利用CollapsingToolbarLayout的标题过渡能力,直接实现标题从Toolbar下方移动到Toolbar内的效果,同时保留你自定义的Toolbar布局:

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="200dp" <!-- 设置足够高度让大标题显示在Toolbar下方 -->
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:title="Contacts"
            app:expandedTitleGravity="bottom|start" <!-- 展开时标题在底部左侧 -->
            app:collapsedTitleGravity="center_vertical|start" <!-- 折叠时标题在Toolbar左侧居中 -->
            app:expandedTitleTextAppearance="@style/ExpandedTitleStyle" <!-- 大标题样式 -->
            app:collapsedTitleTextAppearance="@style/CollapsedTitleStyle"> <!-- 折叠后标题样式 -->

            <!-- 自定义Toolbar,固定在顶部 -->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin">
                
                <!-- 你的自定义内容:导航图标、ImageView等 -->
                <ImageView
                    android:id="@+id/navIcon"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/ic_menu"/>
                <!-- 其他自定义View -->

            </androidx.appcompat.widget.Toolbar>

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

在res/values/styles.xml中定义标题样式:

<style name="ExpandedTitleStyle" parent="@android:style/TextAppearance.Large">
    <item name="android:textSize">32sp</item>
    <item name="android:textColor">@color/black</item>
    <item name="android:paddingStart">16dp</item>
    <item name="android:paddingBottom">16dp</item>
</style>

<style name="CollapsedTitleStyle" parent="@android:style/TextAppearance.Medium">
    <item name="android:textSize">18sp</item>
    <item name="android:textColor">@color/black</item>
    <item name="android:paddingStart">16dp</item>
</style>

关键调整说明:

  1. 移除了CollapsingToolbarLayout内部嵌套的AppBarLayout,Toolbar直接作为CollapsingToolbar的子View,设置layout_collapseMode="pin"确保滚动时固定在顶部。
  2. 给CollapsingToolbarLayout设置固定高度(200dp),让展开状态下标题能显示在Toolbar下方区域。
  3. 通过expandedTitleGravity和collapsedTitleGravity控制标题位置,实现滚动时从底部移动到Toolbar内的效果。
  4. 用expandedTitleTextAppearance和collapsedTitleTextAppearance分别定义展开/折叠时的标题大小、间距,自动过渡。

方案二:自定义标题+Kotlin滚动监听(完全自定义动画)

如果需要更灵活的动画效果(比如非线性移动、自定义透明度变化),可以通过监听AppBarLayout的滚动进度实现:

布局调整:

在CollapsingToolbarLayout中添加下方的大标题,同时在Toolbar中添加一个默认隐藏的小标题:

<!-- 省略CoordinatorLayout和AppBarLayout结构 -->
<com.google.android.material.appbar.CollapsingToolbarLayout
    ...>

    <!-- 下方的大标题 -->
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/expandedTitleTv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Contacts"
        android:textSize="32sp"
        android:paddingStart="16dp"
        android:paddingBottom="16dp"
        android:layout_gravity="bottom|start"/>

    <androidx.appcompat.widget.Toolbar
        ...>
        <!-- 自定义导航图标等 -->
        <!-- Toolbar内的小标题,默认隐藏 -->
        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/collapsedTitleTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Contacts"
            android:textSize="18sp"
            android:visibility="invisible"
            android:layout_marginStart="16dp"/>
    </androidx.appcompat.widget.Toolbar>

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

Kotlin代码实现监听:

appBarLayout.addOnOffsetChangedListener { _, verticalOffset ->
    val totalScrollRange = appBarLayout.totalScrollRange
    // 计算滚动进度(0=完全展开,1=完全折叠)
    val progress = Math.abs(verticalOffset).toFloat() / totalScrollRange.toFloat()

    // 大标题向上移动,跟随滚动进度
    expandedTitleTv.translationY = -verticalOffset.toFloat()
    // 大标题逐渐隐藏
    expandedTitleTv.alpha = 1 - progress

    // 小标题逐渐显示
    collapsedTitleTv.alpha = progress
    collapsedTitleTv.visibility = if (progress > 0.5f) View.VISIBLE else View.INVISIBLE
}

总结

  • 优先选择方案一,利用Material组件原生特性,无需额外代码,结构更稳定。
  • 方案二适合需要完全自定义动画逻辑的场景,通过滚动监听实现精细控制。

内容的提问来源于stack exchange,提问作者Robert Pal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:47:34