android 折叠式标题栏,12Material Design-可折叠式标题栏

本文介绍了基于CollapsingToolbarLayout实现Android折叠式标题栏的方法。包括创建水果详情界面布局,编写FruitActivity代码处理数据和按钮事件,处理RecyclerView点击事件。还实现了系统差异型效果,让背景图与状态栏融合,提升视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CollapsingToolbarLayout

这个是作用域Toolbar基础之上的布局,也是Design Support库提供的,可以让Toolbar的效果变得更加的丰富

CollapsingToolbarLayout是不能独立存在的,它只能是AppBarLayout的直接子布局,而AppBarLayout又必须是CoordinatorLayout的子布局,因此这次实现的功能需要综合前面所学的各种知识

首先需要一个额外的活动作为水果的详情展示界面,右击包-->New-->Activity-->Empty Activity,创建一个FruitActivity,布局为activity_fruit.xml,然后编写水果详情界面布局

在activiyt_fruit.xml中的内容主要分为两个部分,第一是水果的标题栏,一个是水果的内容详情,首先是标题栏部分,使用CoordinatorLayout作为最外层的布局

要注意的就是xmlns:app

在CoordinatorLayout中嵌套一个AppBarLayout

这里指定了一个AppBarLayout的id,宽度指定为250dp

在AppBarLayout中嵌套一个CollapsingToolbarLayout

其中 android:theme属性是指定主题,

app:contentScrim属性是用于指定CollapsingToolbarLayout在趋于折叠状态以及折叠之后的背景色

app:layout_scrollFlags属性,scroll表示CollapsingToolbarLayout会随着水果内容详情的滚动一起滚动,enterAlwaysCollapsed表示CollapsingToolbarLayout随着滚动完成后折叠之后就保留在界面上,不再移除屏幕

在CollapsingToolbarLayout中定义标题栏具体的内容

在CollapsingToolbarLayout中定义一个ImageView和Toolbar,这就意味着高级版的标题栏将是由普通的标题栏加上图片组合

其中app:layout_collapseMode属性是用于指定当前控件在CollapsingToolbarLayout折叠过程中的折叠模式,其中的Toolbar指定pin表示在折叠过程中位置始终保持不变,ImageView指定parallax表示在折叠过程中产生一定的错位偏移,这种模式的视觉效果会非常好

水果的标题栏界面完成了,开始编写水果内容详情部分,继续在actvity_fruit.xml中修改代码,如下

...

这里在水果详情的最外层布局中使用了一个NestedScrollView,注意:和AppBarLayout是平级的,

之前学的ScrollView它允许使用滚动的方式查看屏幕以外的数据,而NestedScrollView在此基础上还增加了嵌套响应滚动事件的功能

注意app:layout_behavior属性,指定一个布局行为,和之前在RecyclerView中的一样

不管是ScrolView还是NestedScrollView,它的内部都只允许存在一个直接子布局,如果想要放入更多的东西的时候,就要在里面先嵌套一个LinearLayout,然后在放入具体的内容

...

在里面嵌套一个LineatLayout,具体的内容在这个里面

使用TextView来显示水果的内容详情,并将TextView放入到卡片式布局中

...

这里为了美观,把TextView放入到了CardView中去了

水果的标题栏和水果内容的详情的界面基本就是这样的,当然了还可以在页面上添加一个悬浮按钮,这样看起来就高大上了一点,这里就加入一个评论的悬浮按钮,首先准备好一张图片,然后修改代码

...

...

这里加入了一个FloatingActionButton,它和AppBarLayout、NestedScrollView是平级的

在FloatingActionButton中是使用了app:layout_anchor属性指定了一个锚点,这里锚点设置为AppBarLayout,这样悬浮按钮就会出现在水果标题栏的区域内

使用app:layout_anchorGravity属性指定悬浮按钮的定位,为右下角

这样activity_fruit.xml布局都编写完了,

界面写完后,就该写FruitActivity中的代码了

package com.example.tool;

public class FruitActivity extends AppCompatActivity {

public static final String FRUIT_NAME = "fruit_name";

public static final String FRUIT_IMAGE_ID = "fruit_image_id";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_fruit);

// 通过这个获取到传入的水果名称和图片资源id

Intent intent = getIntent();

String fruitName = intent.getStringExtra(FRUIT_NAME);

int fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID,0);

Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar_1);

CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout)findViewById(R.id.collapsing_toolbar);

ImageView fruitImageVIew = (ImageView)findViewById(R.id.fruit_image_view);

TextView fruitContentText = (TextView)findViewById(R.id.fruit_content_text);

setSupportActionBar(toolbar);

// 启用HomeAsUp按钮

ActionBar actionBar = getSupportActionBar();

if (actionBar != null){

actionBar.setDisplayHomeAsUpEnabled(true);

}

// 将水果的名称设置为当前的界面标题

collapsingToolbar.setTitle(fruitName);

// 传入水果图片,设置到标题栏上面

Glide.with(this).load(fruitImageId).into(fruitImageVIew);

// 生成一堆字符串设置到TextView上面

String fruitContent = generateFruitContent(fruitName);

fruitContentText.setText(fruitContent);

}

private String generateFruitContent(String fruitName){

StringBuilder fruitContent = new StringBuilder();

for (int i=0;i<500;i++){

fruitContent.append(fruitName);

}

return fruitContent.toString();

}

// 处理HomeAsUp按钮的点击事件

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()){

case android.R.id.home:

finish();

return true;

}

return super.onOptionsItemSelected(item);

}

}

首先在onCreate()方法中通过Intent获取到传入的水果的名称和水果图片的id,然后获取到布局文件中的定义的各个控件的实例

使用了Toolbar的标准用法,将它作为ActionBar显示,并启用HomeAsUp按钮,由于HomeAsUp默认就是一个返回的箭头,这里不用修改

调用 collapsingToolbar.setTitle()方法设置水果名为当前界面的标题,然后使用Glide加载传入的水果图片,并设置到标题栏的ImageView中

水果的内容详情,这里使用generateFruitContent()方法获取一堆数据,传入到 fruitContentText.setText()方法中

最后在 onOptionsItemSelected()方法中处理了HomeAsUp按钮的点击事件,点击的时候调用finish(),从而就返回上一个活动了

最后,就是处理RecyclerView的点击事件了,修改FruitAdapter中的代码

public class FruitAdapter extends RecyclerView.Adapter{

...

@Override

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

if (mContext==null){

mContext=parent.getContext();

}

View view= LayoutInflater.from(mContext).inflate(R.layout.fruit_item,parent,false);

final ViewHolder holder=new ViewHolder(view);

holder.cardView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

int position=holder.getAdapterPosition();

Fruit fruit=mFruitList.get(position);

Intent intent=new Intent(mContext,FruitActivity.class);

intent.putExtra(FruitActivity.FRUIT_NAME,fruit.getName());

intent.putExtra(FruitActivity.FRUIT_IMAGE_ID,fruit.getImageId());

mContext.startActivity(intent);

}

});

return holder;

}

...

}

这里给CardView注册了一个点击事件监听器,然后在点击事件中获取当前点击项的水果名和水果资源id,传入到Intent中,最后调用startActivity()方法中启动

此时运行程序,点击任何一个按钮

10b6c48f7dc2048ba349ed9bffc9b9be.png

水果详情页面效果图.png

当拖动水果内容的时候,你会发现水果上的背景图片慢慢变小,一直拖得话,标题栏就会完全折叠

531fb88f2d7016f57c0313cbf4326d9b.png

标题栏完全折叠.png

此时标题栏的背景完全不见了,悬浮按钮也会自动消失,现在的水果标题栏就会自动的变成普通的Toolbar

充分利用系统状态栏空间

你会发现水果的背景图片和系统的状态栏总有一些不搭的感觉,如果我们能将背景图片和状态栏融合到一起,那么就会更好了

在Android5.0系统之前,我们无法对状态栏的背景或颜色进行操作的,那个时候也还没有Material Design的概念。但是Android5.0及之后的系统都是支持这个功能的,因此这里我们就实现一个系统差异型的效果,在Android5.0及之后的系统中,使用背景图和状态栏融合的模式,这之前的系统中使用普通模式。

要想让背景图能够和状态栏融合,需要借助android:fitsSystemWindows这个属性来实现。在CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout这种嵌套结构的布局中,将控件的android:fitsSystemWindows属性指定为true,就表示该控件会出现在系统状态栏里。对应到我们的程序中,那就是水果标题栏中的ImageView应该设置这个属性了。不过只给ImageView设置这个属性是没用的,我们必须将ImageView布局中的所有父布局都设置上这个属性才可以,修改activity_fruit.xml中的代码,如下所示:

...

...

但是,即使我们将android:fitsSystemWindows属性都设置好了还是没用的,因为还必须在程序的主题中将状态栏颜色指定成透明色才行。指定成透明色的方法很简单,在主题中将android:statusBarColor属性的值指定成@android:color/transparent就可以了。但问题在于,android:statusBarColor这个属性是从API21,也就是Android5.0系统才有的,之前的系统无法使用这个属性。那么,系统差异型的功能实现就要从这里开始了

右击res目录->New->Directory,创建一个values-v21目录,然后在此目录下创建一个styles.xml文件。接着对这个文件进行编写,代码如下所示:

这里我们定义了一个FruitActivityTheme主题,它是专门给FruitActivity使用的。我们在FruitActivityTheme中将状态栏的颜色指定成透明色,由于values-v21目录是只有Android5.0及以上系统才会去读取的,因此这么声明是没有问题的。

但是Android5.0之前的系统却无法识别FruitActivityTheme这个主题,因此我们还需要对values/styles.xml文件进行修改,如下所示:

可以看到,这里也定义了一个FruitActivityTheme主题,并且parent主题也是AppTheme,但是它的内部是空的。

最后,还得让FruitActivity使用这个主题才行,修改AndroidManifest.xml中的代码,如下所示:

...

这里使用了 android:theme="@style/FruitActivityTHeme"指定了主题,这样就可以了

e823df23a1f3526b74f6f0f838954d16.png

背景图和状态栏融合.png

这两种视觉绝对不是一个档次上的

<think>好的,我现在需要帮助用户找到实现可折叠标题栏的代码示例。根据用户提供的引用内容,主要是关于使用CollapsingToolbarLayout、AppBarLayout和CoordinatorLayout这些组件。首先,我得回忆一下AndroidMaterial Design的相关知识,特别是可折叠标题栏的实现步骤。 用户提到的引用[2]指出,CollapsingToolbarLayout必须作为AppBarLayout的直接子布局,而AppBarLayout又必须放在CoordinatorLayout里面。所以,布局结构应该是CoordinatorLayout包含AppBarLayout,AppBarLayout再包含CollapsingToolbarLayout,然后在CollapsingToolbarLayout中添加ImageView和Toolbar。另外,引用[3]提到了app:layout_collapseMode属性,用于设置折叠,Toolbar通常设为pin,ImageView设为parallax,这样可以有视差效果。 接下来,我需要整理一个典型的XML布局示例。可能需要包含这些组件,并设置相应的属性。例如,CollapsingToolbarLayout需要设置app:layout_scrollFlags,而里面的子控件需要设置app:layout_collapseMode。同时,CoordinatorLayout还需要包含一个可滚动的视图,比如NestedScrollView或RecyclerView,并设置app:layout_behavior属性,这样滚动时才能触发折叠效果。 然后,用户可能需要Java或Kotlin代码来配合布局,但根据引用内容,主要是在布局文件里设置属性。不过可能需要设置Toolbar作为ActionBar,并启用返回按钮等。例如在Activity中调用setSupportActionBar(toolbar)并设置displayHomeAsUpEnabled。 另外,引用[1]提到CollapsingToolbarLayout可以响应RecyclerView的滚动事件,所以在示例中可能需要包含RecyclerView或NestedScrollView,并确保它们的布局行为正确。同时,可能需要设置内容折叠时的标题和展开时的标题,通过CollapsingToolbarLayout的app:title属性。 现在,我需要将这些元素整合成一个完整的示例,包括XML布局和必要的Activity代码。需要注意各组件之间的嵌套关系,属性的正确使用,比如layout_scrollFlags和layout_behavior。同时,要确保示例代码的准确性和可运行性,避免语法错误。 最后,生成相关问题,可能涉及优化、其他折叠效果或与其他组件的结合使用,比如如何添加图片加载、处理滚动冲突等。</think>以下是一个实现可折叠标题栏的XML布局代码示例,基于Material Design组件: ```xml <!-- 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" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/appBar" android:layout_width="match_parent" android:layout_height="250dp"> <com.google.android.material.appbar.CollapsingToolbarLayout android:id="@+id/collapsingToolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:title="可折叠标题"> <ImageView android:id="@+id/headerImage" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/header_image" app:layout_collapseMode="parallax"/> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin"/> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <!-- 内容区域 --> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/long_text_sample"/> </androidx.core.widget.NestedScrollView> </androidx.coordinatorlayout.widget.CoordinatorLayout> ``` 关键实现要点: 1. 必须使用$CoordinatorLayout$作为根容器[^2] 2. $CollapsingToolbarLayout$需设置$app:layout_scrollFlags="scroll|exitUntilCollapsed"$实现滚动折叠 3. 图片使用$app:layout_collapseMode="parallax$产生视差效果 4. 工具栏使用$app:layout_collapseMode="pin"$保持固定[^3] Java代码补充: ```java // MainActivity.java protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); } CollapsingToolbarLayout collapsingLayout = findViewById(R.id.collapsingToolbar); collapsingLayout.setExpandedTitleColor(Color.TRANSPARENT); // 展开时隐藏标题 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值