欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android折叠式Toolbar使用完全解析(CollapsingToolbarLayout)

程序员文章站 2023-12-17 23:26:04
简介 在各种不同的应用中,大家可能会经常见到这样一个效果:toolbar是透明的,有着一个背景图片以及大标题,随着页面向上滑动,其标题逐渐缩放到toolbar上,而背景图...

简介

在各种不同的应用中,大家可能会经常见到这样一个效果:toolbar是透明的,有着一个背景图片以及大标题,随着页面向上滑动,其标题逐渐缩放到toolbar上,而背景图片则在滑动到一定程度后变成了toolbar的颜色,这种效果也即是折叠式效果。其实这种效果在github上面已经有很多开源库实现了,但是google在其推出的design library库中也给出了一个这种控件,让我们很方便地实现了这种效果。这个控件是collapsingtoolbarlayout,它是一个增强型的framelayout。那么,本篇文章就给大家详细地介绍该控件的使用方法以及注意事项。

效果

本文结合一个demo来进行演示,下面是最终的显示效果,也即折叠式toolbar的效果:

Android折叠式Toolbar使用完全解析(CollapsingToolbarLayout)

引入

使用该控件,需要引入android design library这个库,同时地,我们需要把app的主题也要做相应的修改以便适应这个控件,所以我们也需要appcompat这个库,那么我们在build.gradle文件中引入如下:

dependencies {
 compile 'com.android.support:cardview-v7:24.1.0' //cardview
 compile 'com.android.support:design:24.1.0'
 compile 'com.android.support:appcompat-v7:24.1.0'
}

本文内容均基于官方文档,有兴趣的读者可以前往官方文档进一步查看(自备*)。

知识储备

接下来,笔者一步步地介绍该控件的用法。首先,我们先来了解这个控件的常用xml属性。

一、常用xml属性介绍

1)contentscrim:当toolbar收缩到一定程度时的所展现的主体颜色。即toolbar的颜色。
2)title:当titleenable设置为true的时候,在toolbar展开的时候,显示大标题,toolbar收缩时,显示为toolbar上面的小标题。
3)scrimanimationduration:该属性控制toolbar收缩时,颜色变化的动画持续时间。即颜色变为contentscrim所指定的颜色进行的动画所需要的时间。
4)expandedtitlegravity:指定toolbar展开时,title所在的位置。类似的还有expandedtitlemargin、collapsedtitlegravity这些属性。
5)collapsedtitletextappearance:指定toolbar收缩时,标题字体的样式,类似的还有expandedtitletextappearance。

二、常见的标志位

一般开发中,collapsingtoolbarlayout不会单独出现在布局文件中,而是作为另一个控件coordinatorlayout的子元素出现,那么coordinatorlayout又是什么呢?其实coordinatorlayout这个控件很强大,能对其子元素实现多种不同的功能,一个常见的用法就是:给它的一个子元素a设置一个layout_scrollflags的属性,然后给另外一个子元素b设置一个layout_behavior=”@string/appbar_scrolling_view_behavior”的属性,这个子元素b一般是一个可以滑动的控件,比如recyclerview、nestedscrollview等,那么当子元素b滑动的时候,子元素a就会根据其layout_scrollflags的属性值而做出不同的改变,所以我们要为collapsingtoolbarlayout设置layout_scrollflags属性。

layout_scrollflags

我们来看看layout_scrollflags有哪几个属性可以选择:
* scroll:所有想要滑动的控件都要设置这个标志位。如果不设置这个标志位,那么view会固定不动。
* enteralways:设置了该标志位后,若view已经滑出屏幕,此时手指向下滑,view会立刻出现,这是另一种使用场景。
* enteralwayscollapsed:设置了minheight,同时设置了该标志位的话,view会以最小高度进度屏幕,当滑动控件滑动到顶部的时候才会拓展为完整的高度。
* exituntilcollapsed:向上滑动时收缩当前view。但view可以被固定在顶部。
可能直接用语言来描述还是有点太抽象,下面会以实际的效果给大家展示这几个标志位的具体作用。

layout_collapsemode

上面提到collapsingtoolbarlayout是一个framelayout,它内部能有多个子元素,而子元素也会有不同的表现。比如说,在上面的gif图中,toolbar在缩放后是固定在顶部的,而imageview则是随着布局的滚动而滚动,也即存在一个相对滚动的过程。所以这些子元素可以添加layout_collapsemode标志位进而产生不同的行为。其实这里也只有两种标志位,分别是:
* pin:有该标志位的view在页面滚动的过程中会一直停留在顶部,比如toolbar可以被固定在顶部
* parallax:有该标志位的view表示能和页面同时滚动。与该标志位相关联的一个属性是:layout_collapseparallaxmultiplier,该属性是视差因子,表示该view与页面的滚动速度存在差值,造成一种相对滚动的效果。

三、常用的层级关系

上面说到collapsingtoolbarlayout一般作为coordinatorlayout的子元素出现,其实如果要实现上面的效果,还需要另外一个控件:appbarlayout。该控件也是design库的控件,作用是把其所有子元素当做一个appbar来使用。一般来说,实现折叠式toolbar可以使用以下的层级关系:

<android.support.design.widget.coordinatorlayout...>
 <android.support.design.widget.appbarlayout...>
  <android.support.design.widget.collapsingtoolbarlayout...>
   <!-- your collapsed view -->
   <view.../>
   <android.support.v7.widget.toolbar.../>
  </android.support.design.widget.collapsingtoolbarlayout>
 </android.support.design.widget.appbarlayout>

 <!-- scroll view -->
 <android.support.v7.widget.recyclerview.../>
</android.support.design.widget.coordinatorlayout>

从上面的层级关系来看,最外面的一层是coordinatorlayout,它有两个子元素,分别是appbarlayout和recyclerview(可滑动控件),而appbarlayout则包裹着collapsingtoolbarlayout,collapsingtoolbarlayout的子元素分别是被折叠的view(可以是一张图片,也可以是一个布局)以及我们的toolbar。

例子①

有了以上的知识储备,我们就可以开始动手写代码了,我们的目标是实现上面的gif图的效果。
1、在activity_main.xml文件中(注:以下注释只是为了方便说明):

<android.support.design.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.support.design.widget.appbarlayout
  android:layout_width="match_parent"
  android:layout_height="200dp"
  android:fitssystemwindows="true">

  <android.support.design.widget.collapsingtoolbarlayout
   android:id="@+id/collapsing_toolbar_layout"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:contentscrim="?attr/colorprimary"  <!--toolbar折叠后的主体颜色 -->
   app:expandedtitlemarginend="10dp"   <!--文字展开时的margin -->
   app:expandedtitlemarginstart="10dp"
   app:collapsedtitletextappearance="@style/textappearance.appcompat.title" <!--字体的表现 -->
   app:layout_scrollflags="scroll|exituntilcollapsed">   


   <imageview
    android:id="@+id/iv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaletype="centercrop"
    app:layout_collapsemode="parallax"    <!--设置imageview可随着滑动控件的滑动而滑动 -->
    app:layout_collapseparallaxmultiplier="0.5"/> <!--视差因子 -->

   <android.support.v7.widget.toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionbarsize"
    app:layout_collapsemode="pin" />  <!--toolbar折叠后固定于顶部 -->
  </android.support.design.widget.collapsingtoolbarlayout>

 </android.support.design.widget.appbarlayout>

 <android.support.v4.widget.nestedscrollview
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:layout_behavior="@string/appbar_scrolling_view_behavior"> <!--为滑动控件设置behavior,这样上面的控件才能做出相应改变 -->

  <linearlayout
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <include layout="@layout/item_card"/>
   <include layout="@layout/item_card"/>
   <include layout="@layout/item_card"/>
   <include layout="@layout/item_card"/>
   <include layout="@layout/item_card"/>
   <include layout="@layout/item_card"/>
   <include layout="@layout/item_card"/>
   <include layout="@layout/item_card"/>

  </linearlayout>
 </android.support.v4.widget.nestedscrollview>
</android.support.design.widget.coordinatorlayout>

与其相关联的item_card.xml布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.cardview
 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="100dp"
 android:layout_margin="5dp"
 app:cardelevation="5dp"
 app:contentpaddingtop="2dp"
 app:contentpaddingbottom="2dp">

 <textview
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="learn and share android"
  android:textsize="20sp"
  android:layout_gravity="center"/>

</android.support.v7.widget.cardview>

2、在mainactivity.java文件中再做出一些处理:

 private imageview iv;
 private collapsingtoolbarlayout collapsingtoolbarlayout;
 private toolbar toolbar;

 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);

  collapsingtoolbarlayout = (collapsingtoolbarlayout) findviewbyid(r.id.collapsing_toolbar_layout);
  iv = (imageview) findviewbyid(r.id.iv);
  toolbar = (toolbar) findviewbyid(r.id.toolbar);

  setsupportactionbar(toolbar);
  toolbar.setnavigationicon(r.mipmap.ic_drawer_home);
  collapsingtoolbarlayout.settitle("designlibrarysample");
  collapsingtoolbarlayout.setcollapsedtitletextcolor(color.white);
  collapsingtoolbarlayout.setexpandedtitlecolor(color.white);
  iv.setimageresource(r.mipmap.ic_bg);
 }

上面,我们为collapsingtoolbarlayout设置了标题,以及收缩时标题的颜色和展开时标题的颜色等。经过上面的一个简单例子,就能实现上面gif图所显示的折叠式toolbar的效果了。

这里先小结一下:在coordinatorlayout作为父布局的情况下,给滑动控件设置一个layout_behavior=”@string/appbar_scrolling_view_behavior”标志位(该behavior系统以及帮我们实现),那么当带有这个标志位的控件滑动的时候会触发带有scroll_flags标志位的另一个控件进行滑动,此时imageview的layout_collapsemode是parallax,所以它会以有视差的方式来相对滑动,而toolbar设置了pin的标记位,所以在收缩后会固定在屏幕顶部。

例子②

在例子①内,我们为collapsingtoolbarlayout设置的scroll_flags是”scroll | exituntilcollapsed”,那么我们把标志位换成别的会有什么不同的效果呢?
在activity_main.xml内,作如下修改:

<android.support.design.widget.collapsingtoolbarlayout
 ...
 app:layout_scrollflags="scroll|enteralwayscollapsed|enteralways">

然后别的不作改动,效果如下:

Android折叠式Toolbar使用完全解析(CollapsingToolbarLayout)

显然,所造成的效果发生了变化,这里toolbar并不一致固定在顶部了,而是随着滑动而滑出了屏幕之外,同时如果手指向下滑动,toolbar会逐渐出现并保持着最小的高度,等到回到了最顶部后,toolbar会展开成原来的样子。
那么,基于以上的例子,如果上面少了一个“enteralwayscollapsed”这个标志位又会怎样呢?该标志位的作用上面也已经解释过了,是控制toolbar以最小的高度进入屏幕,并且在滑动控件滑动到最顶端的时候再展开成完整的高度。如果少了这个标志位,在我们手指向下滑的时候,toolbar也会逐渐出现,但是与上面gif图不同的是,toolbar会继续展开变成原来的样子,即出现imageview。图这里就不放出来了,读者可以自行验证~

通过以上的两个小例子,我们对collapsingtoolbarlayout有了一定的认识,也学会了它的使用方法了,使用它能让我们的应用变得更加美观。那么最后,我们再来谈谈注意事项,也即笔者开发过程中遇到的坑。

注意事项

1、android design support library的使用需要配合特定的主题,一般用appcompat下的主题即可,也可以自定义主题,继承自appcompat的主题,否则会报错。另外如果使用android studio的话,主题的相关代码需要在styles.xml(v21)文件内做出相应的修改,否则使用android 5.0以上的机子做测试的话也会报错。
2、由于使用了appcompat的主题,那么我们的activity应该继承自appcompatactivity。
3、笔者之前使用design support library的版本号是23.1.0,在此版本上,collapsingtoolbarlayout没有设置collapsedtitletextappearance属性,标题可以正常显示,然而到了24.1.0版本,即上面所用的版本,如果没有设置collapsedtitletextappearance属性,则当toolbar收缩后,其标题文字变得非常小。所以我们要设置collapsedtitletextappearance=”@style/textappearance.appcompat.title”这个属性,才能变得正常。
4、如果没有为collapsingtoolbarlayout设置一个title,那么会使用actionbar自带的标题来显示应用的名称,这是因为调用了setsupportactionbar(toolbar)函数。

最后附上代码的地址:designsupportlibrarysample

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: