写点什么

玩转 AppBarLayout,更酷炫的顶部栏

用户头像
Android架构
关注
发布于: 5 小时前

如果 Toolbar 仅仅是用来对以往的 ActionBar 做一次替换,那也太没创意啦!完全没必要去替换了,因为它们表现出来的都是一样的,而且并没有让我们觉得用起来比 ActionBar 方便。那为啥要替换呢,总应该有他的理由吧:ActionBar 是固定在顶部,并不能移动,我觉得这是最大的不好,而我们的 ToolBar 可以让我们随便摆放,就就可以带来很多灵活性和效果啦!


正如你所看的这样,Toolbar 根本就不够看的,一点都不复杂。接下来我们继续学习在 Toolbar 上面再套一层父 View,让 Toolbar 更有互动性。

2 AppBarLayout

AppBarLayout 继承自 LinearLayout,布局方向为垂直方向。所以你可以把它当成垂直布局的 LinearLayout 来使用。AppBarLayout 是在 LinearLayou 上加了一些材料设计的概念,它可以让你定制当**某个可滚动 View**的滚动手势发生变化时,其内部的子 View 实现何种动作。


请注意:上面提到的**某个可滚动 View**,可以理解为某个 ScrollView。怎么理解上面的话呢?就是说,当某个 ScrollView 发生滚动时,你可以定制你的“顶部栏”应该执行哪些动作(如跟着一起滚动、保持不动等等)。那某个可移动的 View 到底是哪个可移动的 View 呢?这是由你自己指定的!如何指定,我们后面说。

2.1 AppBarLayout 子 View 的动作

内部的子 View 通过在布局中加app:layout_scrollFlags设置执行的动作,那么app:layout_scrollFlags可以设置哪些动作呢?分别如下:


(1) scroll:值设为scroll的 View 会跟随滚动事件一起发生移动。


什么意思呢?简单的说,就是当指定的 ScrollView 发生滚动时,该 View 也跟随一起滚动,就好像这个 View 也是属于这个 ScrollView 一样。


一张 gif 足以说明:



_


scroll


_


对应的布局文件


<android.support.design.widget.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content">


<android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?android:attr/actionBarSize"android:background="?attr/colorPrimary"app:layout_scrollFlags="scroll" /></android.support.design.widget.AppBarLayout>


(2) enterAlways:值设为enterAlways的 View,当 ScrollView 往下滚动时,该 View 会直接往下滚动。而不用考虑 ScrollView 是否在滚动。


看个动画片(Y(^o^)Y)(ToolBar 高度设为:?android:attr/actionBarSize,app:layout_scrollFlags="scroll|enterAlways"):



_


scroll|enterAlways


_


(3) exitUntilCollapsed:值设为exitUntilCollapsed的 View,当这个 View 要往上逐渐“消逝”时,会一直往上滑动,直到剩下的的高度达到它的最小高度后,再响应 ScrollView 的内部滑动事件。


怎么理解呢?简单解释:在 ScrollView 往上滑动时,首先是 View 把滑动事件“夺走”,由 View 去执行滑动,直到滑动最小高度后,把这个滑动事件“还”回去,让 ScrollView 内部去上滑。看个 gif 感受一下(图中将高度设的比较大:200dp,并将最小高度设置为?android:attr/actionBarSize,app:layout_scrollFlags="scroll|exitUntilCollapsed"):



_


scroll|exitUntilCollapsed


_


(4) enterAlwaysCollapsed:是enterAlways的附加选项,一般跟enterAlways一起使用,它是指,View 在往下“出现”的时候,首先是enterAlways效果,当 View 的高度达到最小高度时,View 就暂时不去往下滚动,直到 ScrollView 滑动到顶部不再滑动时,View 再继续往下滑动,直到滑到 View 的顶部结束。


来个 gif 感受一下(图中将高度设的比较大:200dp,并将最小高度设置为?android:attr/actionBarSize,app:layout_scrollFlags="scroll|enerAlways|enterAlwaysCollapsed"):



_


scroll|enerAlways|enterAlwaysCollapsed


_

2.2 将 AppBarLayout 与 ScrollView 关联起来

前面说了一直反复说“当 ScrollView 发生滚动时”,那么怎么将 AppBarLayout 与 ScrollView 关联起来呢?我们注意到,AppBarLayout 与 ScrollView 之间动作“相互依赖”,这不就是我们上一篇《CoordinateLayout的使用如此简单 》所学的内容吗?把 ScrollView 和 AppBarLayout 作为 CoordinateLayout 的子 View,然后编写一个 Behavior,在这个 Behavior 里面判断当前的操作是应该让 ScrollView 时刻保持在 AppBarLayout 之下(即只要改变 AppBarLayout 的位置就可以一起滑动),还是应该让 ScrollView 内部滚动而不让 AppBarLayout 位置发生变化等等这些需求,都是可以在 Behavior 里面处理的。你可以去针对你的 ScrollView 编写 Behavior。然而,我们看到我们的 AppBarLayout 事先的功能比较复杂,如果我们自己去定义这样的效果,代码非常复杂,还要考虑很多方面,好在 Android 帮我们写好啦,我们直接用就是了,这个 ScrollView 就是 NestedScrollView,请注意,它并没有继承 ScrollView,它继承的是 FrameLayout,但是它实现的效果把它可以看成是 ScrollView。


把 NestedScrollView 放入到我们的 layout 文件里面就可以啦~~~,很方便~


<android.support.v


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


4.widget.NestedScrollView


android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_behavior="@string/appbar_scrolling_view_behavior">


</android.support.v4.widget.NestedScrollView>


有没有注意到有个属性:app:layout_behavior="@string/appbar_scrolling_view_behavior",它就是指定 Behavior 的,appbar_scrolling_view_behavior对应的类的名称是:android.support.design.widget.AppBarLayout$ScrollingViewBehavior感兴趣的可以去分析源码。


好了,我们现在会用 AppBarLayout 啦~是不是发现用起来 so easy!接下来我们把剩下CollapsingToolbarLayout的给"消化"掉!

3 CollapsingToolbarLayout

CollapsingToolbarLayout是用来对Toolbar进行再次包装的ViewGroup,主要是用于实现折叠(其实就是看起来像伸缩~)的 App Bar 效果。它需要放在AppBarLayout布局里面,并且作为AppBarLayout的直接子ViewCollapsingToolbarLayout主要包括几个功能(参照了官方网站上内容,略加自己的理解进行解释):


(1) 折叠 Title(Collapsing title):当布局内容全部显示出来时,title 是最大的,但是随着 View 逐步移出屏幕顶部,title 变得越来越小。你可以通过调用 setTitle 函数来设置 title。

(2)内容纱布(Content scrim):根据滚动的位置是否到达一个阀值,来决定是否对 View“盖上纱布”。可以通过 setContentScrim(Drawable)来设置纱布的图片.

(3)状态栏纱布(Status bar scrim):根据滚动位置是否到达一个阀值决定是否对状态栏“盖上纱布”,你可以通过setStatusBarScrim(Drawable)来设置纱布图片,但是只能在LOLLIPOP设备上面有作用。

(4)视差滚动子 View(Parallax scrolling children):子 View 可以选择在当前的布局当时是否以“视差”的方式来跟随滚动。(PS:其实就是让这个 View 的滚动的速度比其他正常滚动的 View 速度稍微慢一点)。将布局参数app:layout_collapseMode设为parallax

(5)将子 View 位置固定(Pinned position children):子 View 可以选择是否在全局空间上固定位置,这对于 Toolbar 来说非常有用,因为当布局在移动时,可以将 Toolbar 固定位置而不受移动的影响。 将app:layout_collapseMode设为pin


了解这些概念后,我们来看看布局吧~


<?xml version="1.0" encoding="utf-8"?><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.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">


<android.support.design.widget.CollapsingToolbarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"app:expandedTitleMarginEnd="64dp"app:expandedTitleMarginStart="48dp"app:layout_scrollFlags="scroll|exitUntilCollapsed">


<ImageViewandroid:id="@+id/main.backdrop"android:layout_width="wrap_content"android:layout_height="300dp"android:scaleType="centerCrop"android:src="@drawable/material_img"app:layout_collapseMode="parallax" />


<android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?android:attr/actionBarSize"app:layout_collapseMode="pin" />


</android.support.design.widget.CollapsingToolbarLayout></android.support.design.widget.AppBarLayout>


<android.support.v4.widget.NestedScrollView


android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingTop="50dp"app:layout_behavior="@string/appbar_scrolling_view_behavior">

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
玩转AppBarLayout,更酷炫的顶部栏