CoordinatorLayout 的基本使用


本文主要梳理下 CoordinatorLayout 、AppBarLayout 和 CollapsingToolbarLayout 组合使用的方法。

一、基本概念

1.1 CoordinatorLayout

CoordinatorLayout 通常作为一个或多个子视图进行交互的布局容器,它的继承关系为:coordinatorLayout
简单翻译就是协调员布局,主要作为与一个或多个子视图进行特定交互的容器,和 AppBarLayout 搭配使用效果极佳。

1.2 AppBarLayout

AppBarLayout 是一个垂直的线性布局,它实现了 Material Designs 的许多特性 AppBar 概念,即滚动手势。AppBarLayout 的子view 应该通过设置 setScrollFlags(int)app:layout_scrollFlags达到所需的滚动行为,它的继承关系为:AppBarLayout
在这里插入图片描述
可以看到AppBarLayout 本质上是一个线性布局,而且是一个垂直方向上的线性布局。AppBarLayout 对象默认配置了一个 Behavior。而正是这个 Behavior ,它会响应外边的嵌套互动事件,然后根据特定的规则去展现和变换内部的子 View。

二、使用方法

2.1 用法

 <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">
  
  		//  app:layout_behavior 这个属性比较重要
       <androidx.core.widget.NestedScrollView
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               app:layout_behavior="@string/appbar_scrolling_view_behavior">
  
           <!-- Your scrolling content -->
  
       </androidx.core.widget.NestedScrollView>
  
       <com.google.android.material.appbar.AppBarLayout
               android:layout_height="wrap_content"
               android:layout_width="match_parent">
  			// 下面这个两个view 可以任意的,可以将需要联动的布局放在此处
  			// 也可以使用系统的 CollapsingToolbarLayout 和 Toolbar 来达到比较好用的效果
           <androidx.appcompat.widget.Toolbar
                   ...
                   app:layout_scrollFlags="scroll|enterAlways"/>
  
           <com.google.android.material.tabs.TabLayout
                   ...
                   app:layout_scrollFlags="scroll|enterAlways"/>
  
       </com.google.android.material.appbar.AppBarLayout>
  
   </androidx.coordinatorlayout.widget.CoordinatorLayout>
   

上述布局中 NestedScrollView 的属性 app:layout_behavior 比较重要,它要和 AppBarLayout 进行绑定,所以它必须指定 Behavior ,这个可以使用系统默认的 @string/appbar_scrolling_view_behavior ,如果有特殊需求也可以自定义 CoordinatorLayout.Behavior。这里的 NestedScrollView 可以替换为 NestedScrollingChild 对象的所有子 View。如图:在这里插入图片描述
可以看到我们经常用的 RecyclerView 都是 NestedScrollingView 的子View。

2.2 layout_scrollFlags

ApBarLayout 本身就是一个垂直方向的 LinearLayout,所以它的滑动主要是针对内部子 View 的滑动。滑动的时候需要定制一个规则。这个规则就是 AppBarLayout 中的内部的子 View 中,在 xml 中用 layout_scrollFlags,layout_scrollFlags的取值有7个:

  • scroll : 该视图将与滚动事件直接相关地滚动。需要将该标志设置为使其他任何标志之前,该标志才能生效。如果在此之前的任何同级视图没有此标志,则此值无效。
  • enterAlways :进入(在屏幕上滚动)时,无论滚动视图是否也在滚动,该视图都会在任何向下滚动事件上滚动。这通常称为“快速返回”模式。
  • enterAlwaysCollapsed:'enterAlways’的附加标志将返回的视图修改为仅最初滚动回到其折叠高度。一旦滚动视图到达其滚动范围的末尾,该视图的其余部分将被滚动到视图中。
  • exitUnitCollapsed:退出时(滚动到屏幕外),视图将一直滚动直到“折叠”为止。折叠后的高度由视图的最小高度定义。
  • snap:滚动结束时,如果视图仅部分可见,则它将被捕捉并滚动到最接近的边缘。
  • snapMargins:与“snap”一起使用的附加标志。如果设置,则视图将被对齐到其顶部和底部边缘,而不是视图本身的边缘。
  • noScroll : 禁用在视图上滚动。此标志不应与任何其他滚动标志结合使用

三、Toolbar

在 Android 的发展历程中,出现了 TitleBar、ActionBar、Toolbar的进化。随后在Material Design 设计中又出现了 AppBar的概念,而 AppBarLayout 则是 AppBar 在 Android 中的代码实现。AppBarLayout 虽然和 ToolBar 没有直接联系,但是当 ToolBar 内置在 AppBarLayout 中的时候,ToolBar 的效果增强了,这使的 AppBarLayout 和 ToolBar 结合使用就非常酷炫的效果。

四、CollapsingToolbarLayout

CollapsingToolbarLayout 出现的主要目的就是为了增强 ToolBar
CollapsingToolbarLayout 是用于 Toolbar 实现折叠应用程序栏的包装器。它旨在用作 AppBarLayout 的子 View。
CollapsingToolbarLayout 包括以下功能:

  1. Collapsing Title(折叠标题)
  2. Content scrim (内容纱布)
  3. Status bar scrim (状态栏纱布)
  4. Parallax scrolling children (子 View 的视差滚动行为)
  5. Pinned position children(子类的位置固定行为)

下面就逐个进行结束这些功能。

4.1 Collapsing Title(折叠标题)

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CollapsingTitleActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:background="@color/teal_200"
        android:layout_width="match_parent"
        android:fitsSystemWindows="true"
        android:layout_height="300dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
            app:title="collapsing title">

            <!--
            app:layout_collapseMode="pin"
            这个设置Toolbar不能隐藏,否则能隐藏
            -->
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolBar"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#4CAF50"
                app:title="我是toolbar标题"
                app:layout_collapseMode="pin" />

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

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

需要注意的是,当 CollapsingToolbarLayout 和 Toolbar 同时设定时,Collapsing Title中的 title 会覆盖 Toolbar 中的 title。Collapsing title 有展开 和 折叠 折两种状态。

4.2 Content scrim (内容纱布)

大部分代码和 4.1 中的一样,只是在 CollapsingToolbarLayout 中设置了 contentScrim 属性,主要代码

 <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
            app:contentScrim="#4CAF50"
            app:title="collapsing title">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@mipmap/ocean"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolBar"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                app:title="我是toolbar标题"
                app:layout_collapseMode="pin" />
                
        </com.google.android.material.appbar.CollapsingToolbarLayout>

在本例子中,内容纱布的主要效果是,当滑动覆盖或显示 AppBarLayout 内部的 view 时,会出现一层覆盖在 Toolbar 下方的 ImageView 上方的一层设置 contentScrim 颜色的纱布。就是在过渡的时候有一个渐变的过程。如果 AppBarLayout 只有 Toolbar ,则没有效果。

4.3 Status bar scrim (状态栏纱布)

效果没有出来,等有空再研究下

4.4 子 View 的视差滚动行为和子类的位置固定行为

CollapsingToolbarLayout 可以控制的子 View 滚动模式有3种:

  1. none 默认,无效果
  2. parallax,视觉差滚动
  3. pin,固定子 View

parallax:这些属性可以通过 app:layout_collapseMode 来进行设置。对子 View 进行控制,视觉差就是 CollapsingToolbarLayout 中有两个子 View ,其中一个 View 设置此属性时,就造成此两个 View 在滚动的时候一个快一个慢,视觉差默认因子 DEFAULT_PARALLAX_MULTIPLIER为0.5,所以设置了 app:layout_collapseMode 的 View 比没有设置改属性的要慢。
pin: CollapsingToolbarLayout 中某个子 View 固定,无论是否存在滚动事件,只要设置 app:layout_collapseMode=”pin” 就可以了

五、AppBarLayout 的滑动监听

AppBarLayout 定义的监听器为:

 onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int)

第一参数是 AppBarLayout ,第二个参数 verticalOffset 是 AppBarLayout 没有完全展开时滑动的距离,初始值为0,其他的时候值为负值,它绝对值的最大值为 AppBarLayout 的 totalScrollRange。可以用如下监听位移方式做一些处理:

        appBarLayout.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
            override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int) {
                Log.d(TAG, "verticalOffset:$verticalOffset")
                if (abs(verticalOffset) == appBarLayout?.totalScrollRange) {
                    Log.d(TAG, "折叠")
                } else {
                    Log.d(TAG, "展开")
                }
            }
        })

大概用法就是这些,还有部分内容需要补充。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值