Android 仿支付宝首页头部伸缩效果及相关控件CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout的使用介绍

首先看效果图:


preview.gif

gradle 关联

implementation 'com.google.android.material:material:1.0.0'

下面介绍示例用到的几个布局:

CoordinatorLayout

CoordinatorLayout 是一个 “加强版” FrameLayout, 它主要有两个用途:

  • 用作应用的顶层布局管理器,也就是作为用户界面中所有 UI 控件的容器;
  • 用作相互之间具有特定交互行为的 UI 控件的容器,通过为 CoordinatorLayout 的子 View 指定 Behavior, 就可以实现它们之间的交互行为。 Behavior 可以用来实现一系列的交互行为和布局变化,比如说侧滑菜单、可滑动删除的 UI 元素,以及跟随着其他 UI 控件移动的按钮等。

AppBarLayout

实际上我们在应用中有 CoordinatorLayout 的地方通常都会有 AppBarLayout 的联用。

AppBarLayout 是一个垂直的 LinearLayout,实现了 Material Design 中 App bar 的 Scrolling Gestures 特性。AppBarLayout 的子 View 应该声明想要具有的“滚动行为”,这可以通过 layout_scrollFlags 属性或是 setScrollFlags() 方法来指定。

AppBarLayout 只有作为 CoordinatorLayout 的直接子 View 时才能正常工作,为了让 AppBarLayout 能够知道何时滚动其子 View,我们还应该在 CoordinatorLayout 布局中提供一个可滚动 View,我们称之为 Scrolling View。

Scrolling View 和 AppBarLayout 之间的关联,通过将 Scrolling View 的 Behavior 设为 AppBarLayout.ScrollingViewBehavior 来建立。

AppBarLayout 主要给子布局配置属性 app:layout_scrollFlags,layout_scrollFlags 的取值可以为以下几种。

  • scroll:设置滚动效果,没有设置这个属性的view将被固定在屏幕顶部
  • enterAlways:与 scroll 类似(scroll|enterAlways),只不过向下滚动先显示 AppBarLayout 到完全,再滚动 Scrolling View
  • enterAlwaysCollapsed:需要和 enterAlways 一起使用(scroll|enterAlways|enterAlwaysCollapsed),和 enterAlways 不一样的是,不会显示 AppBarLayout 到完全再滚动 Scrolling View,而是先滚动 AppBarLayout 到最小高度,再滚动 Scrolling View,最后再滚动 AppBarLayout 到完全显示。
    注意:需要定义 View 的最小高度(minHeight)才有效果:
    android:minHeight="10dp"
    app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
    
  • exitUntilCollapsed:当本 View 离开屏幕时,会被“折叠”直到达到其最小高度。我们可以这样理解这个效果:当我们开始向上滚动 Scrolling view 时,本 View 会先接管滚动事件,这样本 View 会先进行滚动,直到滚动到了最小高度(折叠了),Scrolling view 才开始实际滚动。而当本 View 已完全折叠后,再向下滚动 Scrolling view,直到 Scrolling view 顶部的内容完全显示后,本 View 才会开始向下滚动以显现出来。
    android:minHeight="10dp"
    app:layout_scrollFlags="scroll|exitUntilCollapsed"
    
  • snap:在一次滚动结束时,本 View 很可能只处于“部分显示”的状态,加上这个标记能够达到“要么完全隐藏,要么完全显示”的效果。例如,如果视图只有底部25%显示,它将折叠。相反,如果它的底部75%可见,那么它将完全展开。

CollapsingToolbarLayout

CollapsingToolbarLayout 继承自 FrameLayout,它是用来实现 Toolbar 的折叠效果,一般它的直接子 View 是 Toolbar,当然也可以是其它类型的 View。

collapsingToolbarLayout 可以作为 AppBarLayout 的子 view,可以控制包含在其中的控件在滚动时的响应事件,子 view 可以是个可折叠的 Toolbar,app:layout_collapseMode 设置折叠模式。

CollapsingToolbarLayout 常用xml属性介绍

  • contentScrim:当Toolbar收缩到一定程度时的所展现的主体颜色。即Toolbar的颜色。
  • title:当titleEnable设置为true的时候,在toolbar展开的时候,显示大标题,toolbar收缩时,显示为toolbar上面的小标题。
  • scrimAnimationDuration:该属性控制 toolbar 收缩时,颜色变化的动画持续时间。即颜色变为 contentScrim 所指定的颜色进行的动画所需要的时间。
  • expandedTitleGravity:指定 toolbar 展开时,title 所在的位置。类似的还有expandedTitleMargin、collapsedTitleGravity 这些属性。
  • collapsedTitleTextAppearance:指定 toolbar 收缩时,标题字体的样式,类似的还有 expandedTitleTextAppearance。

app:layout_collapseMode 折叠模式:

  • pin:折叠后,此布局将固定在顶部。
  • parallax:折叠时,此布局也会有视差折叠效果。
    当其子布局设置了parallax模式时,我们还可以通过app:layout_collapseParallaxMultiplier 设置视差滚动因子,值为:0~1。

实现过程

1、 coordinatorLayout 嵌套 appBarLayout 。
2、appBarLayout 的子 view collapsingToolbarLayout 设置属性app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
让头部随着内容下拉而展开,随着内容上拉而收缩。
3、collapsingToolbarLayout 的子布局有两种,展开时显示的布局和 Toolbar,其中 Toolbar 又包含了两种布局,展开时的和收缩时的。 展开时,(扫一扫、付钱)的布局:


layout_marginTop="50dp" 预留出 toolbar 的高度,避免布局重叠。

toolbar里的两种布局:




        

        


toolbar 里的两个布局,可以通过监听 AppBarLayout 的移动控制显示和隐藏。

4、滑动过程中,各控件的透明度会有渐变的效果,这里采用类似遮罩的效果,每个 include 布局里都有个遮罩的 view,在滑动过程中监听 appBarLayoutaddOnOffsetChangedListener,通过计算滑动的距离,逐渐改变透明度。

/**
     * 通过计算滑动的距离,逐渐改变透明度。
     */
    override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) {
        //垂直方向偏移量
        val offset = Math.abs(verticalOffset)
        //最大偏移距离
        val scrollRange = appBarLayout.totalScrollRange
        //当滑动没超过一半,展开状态下 toolbar 显示内容,更具收缩位置,改变透明值
        if (offset <= scrollRange / 2) {
            toolbar_open.visibility = View.VISIBLE
            toolbar_close.visibility = View.GONE
            //根据偏移百分比 计算透明值
            val scale: Float = offset.toFloat() / (scrollRange / 2)
            val alpha: Int = (255 * scale).toInt()
            bg_toolbar_open.setBackgroundColor(Color.argb(alpha, 25, 131, 209))
        }
        //当滑动超过一半,收缩状态下 toolbar 显示内容,根据收缩位置,改变透明值
        else {
            toolbar_open.visibility = View.GONE
            toolbar_close.visibility = View.VISIBLE
            val scale = (scrollRange - offset).toFloat() / (scrollRange / 2)
            val alpha = (255 * scale).toInt()
            bg_toolbar_close.setBackgroundColor(Color.argb(alpha, 25, 131, 209))
        }
        //根据百分比计算扫一扫布局透明值
        val scale = offset.toFloat() / scrollRange
        val alpha = (255 * scale).toInt()
        bg_content.setBackgroundColor(Color.argb(alpha, 25, 131, 209))
    }

详细代码见 :
github地址:https://github.com/wuchao226/AliHome

你可能感兴趣的:(Android 仿支付宝首页头部伸缩效果及相关控件CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout的使用介绍)