文章目录
- [1 CollapsingToolbarLayout概述](#1 CollapsingToolbarLayout概述)
- [2 实现Toolbar折叠效果](#2 实现Toolbar折叠效果)
-
- [2.1 编码](#2.1 编码)
- [2.2 效果图](#2.2 效果图)
Toolbar的折叠和隐藏效果更推荐使用MotionLayout 来实现,此文仅为记录CollapsingToolbarLayout的用法。
1 CollapsingToolbarLayout概述
CollapsingToolbarLayout继承自FrameLayout,它的作用是提供一个可以折叠的Toolbar,设置它的layout_scrollFlag属性,可以控制包含在CollapsingToolbarLayout中的控件,如ImageView、Toolbar在响应layout_behavior事件时做出的相应的scrollFlags滚动事件。
CollapsingToolbarLayout的源码:
java
package com.google.android.material.appbar;
public class CollapsingToolbarLayout extends FrameLayout {
//...省略其它源码
}
2 实现Toolbar折叠效果

项目结构
2.1 编码
app模块下的build.gradle:
groovy
plugins {
alias(libs.plugins.android.application)
}
android {
namespace 'com.example.collapsingtoolbardemo'
compileSdk 36
defaultConfig {
applicationId "com.example.collapsingtoolbardemo"
minSdk 24
targetSdk 36
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
dependencies {
implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
}
activity_main.xml:
注意:AppBarLayout必须是第一个嵌套在CoordinatorLayout里面的子View。
xml
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:collapsedTitleGravity="start"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="center_horizontal|bottom"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
tools:title="CollapsingToolbarLayout标题">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/mao" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
tools:title="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"
android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
CollapsingToolbarLayout属性说明:
app:contentScrim="?attr/colorPrimary",用来设置CollapsingToolbarLayout收缩后最顶部的颜色。
app:expandedTitleGravity="center_horizontal|bottom",表示将此CollapsingToolbarLayout完全展开后,title所处的位置,默认值为left+bottom。
app:collapsedTitleGravity="start",表示当头部的衬图ImageView消失后,此title将回归到Toolbar的位置,默认值为left。
app:layout_scrollFlags="scroll|exitUntilCollapsed",用来设置滚动事件,属性里面必须至少启用scroll这个flag,这样View才会滚动出屏幕,否则将一直固定在顶部。scroll|exitUntilCollapsed能实现折叠效果,scroll|enterAlways则实现隐藏效果。
此外,
要定义AppBarLayout与滚动视图之间的联系,Design Support Library包含了一个特殊的字符串资源 @string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用来通知AppBarLayout何时发生了滚动事件。
这个Behavior需要设置在触发事件的View上,即布局中的RecyclerView的属性app:layout_behavior="@string/appbar_scrolling_view_behavior"。
当然,AppBarLayout中的子View需要设置app:layout_scrollFlags属性,否则就算接收到RecyclerView滚动事件,AppBarLayout也不会有什么反应。
RecyclerView的item布局文件:
xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/img"
app:layout_constraintTop_toTopOf="parent"
tools:text="提示文字" />
</androidx.constraintlayout.widget.ConstraintLayout>
RecyclerViewAdapter.java:
java
package com.example.collapsingtoolbardemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
/**
* Created by Administrator on 2025/8/13.
*/
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private Context mContext;
private List<String> mContents;
public RecyclerViewAdapter(Context context, List<String> content) {
mContext = context;
mContents = content;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final View view = holder.mView;
TextView tv = view.findViewById(R.id.tv);
tv.setText(mContents.get(position));
view.setOnClickListener(v -> Toast.makeText(mContext, mContents.get(position), Toast.LENGTH_SHORT).show());
}
@Override
public int getItemCount() {
return mContents.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
mView = itemView;
}
}
}
MainActivity.java:
java
package com.example.collapsingtoolbardemo;
import android.graphics.Color;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import java.util.ArrayList;
import java.util.List;
/**
* 参考资料:刘望舒.Android进阶之光[M].北京:电子工业出版社,2018
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
/*ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});*/
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
// 会覆盖Toolbar中的app:title属性
//collapsingToolbarLayout.setTitle("多来啊梦");
AppBarLayout appBarLayout = findViewById(R.id.appbar);
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
// 当verticalOffset接近0时,表示图片滑动到了顶部,此时可以显示标题
if (Math.abs(verticalOffset) - appBarLayout.getTotalScrollRange() == 0) {
collapsingToolbarLayout.setTitle("哆啦A梦");
} else {
// 否则隐藏标题
collapsingToolbarLayout.setTitle("");
}
}
});
RecyclerView rv = findViewById(R.id.recyclerView);
rv.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL));
rv.setItemAnimator(new DefaultItemAnimator());
List<String> content = new ArrayList<>();
content.add("djjjj减肥萨达");
content.add("发多少");
content.add("阿范德萨发");
content.add(" 额阿帆");
content.add("答复");
content.add("大师傅");
content.add(" 阿发");
content.add(" e网通");
content.add(" 二二");
content.add("阿凡达");
content.add("让他无任何");
content.add("如图");
content.add(" 人物");
content.add(" 人员无人");
content.add("热突然");
content.add("提问题");
content.add(" 人特意");
content.add(" 人特意");
content.add(" 团任务");
content.add("日dsf");
content.add("dfas a");
content.add("dthtrtr");
content.add("rhetr");
content.add(" yhjteyt");
content.add(" trey5tr");
content.add("ulotu");
content.add("rewr5");
content.add(" iryyte");
content.add(" ytrry");
content.add(" uouyrw");
content.add("krejhhg");
rv.setAdapter(new RecyclerViewAdapter(this, content));
}
}
2.2 效果图

折叠Toolbar
参考文献:
1 刘望舒.Android进阶之光M.北京:电子工业出版社,2018
关注我:Accrual