应用栏布局AppBarLayout

Android5.0推出工具栏Toolbar用来替代ActionBar,灵活性和易用性大大增强,有关Toolbar的详细介绍参见《 Android开发笔记(一百一十九)工具栏Toolbar》。

可是仅仅使用Toolbar的话,还是有些呆板,比如说Toolbar固定占据着页面顶端,既不能跟着主体页面移上去,也不会跟着主体页面拉下来。为了让App页面更加生动活泼,势必要求Toolbar在某些特定的场景上移或者下拉,如此才能满足酷炫的页面特效需要。那么Android5.0也同时给出了相应的解决方案,即推出MaterialDesign库,通过该库中的AppBarLayout控件,对Toolbar加以包装,从而实现顶部工具栏的动态变化效果。

AppBarLayout其实继承自LinearLayout,所以具备LinearLayout的所有属性与方法。对于大家关心的额外功能,则主要有以下几点:
1、支持响应主体页面的滑动行为,即在主体页面上移或者下拉时,AppBarLayout能够捕捉到主体页面的滚动操作;
2、AppBarLayout捕捉到滚动操作之后,还要通知头部控件(通常是Toolbar),告诉头部控件你要怎么滚,是爱咋咋滚,还是满大街滚;

具体到实现上,要在工程中做以下修改:
1、添加几个库的支持,包括appcompat-v7库(Toolbar需要)、design库(AppBarLayout需要)、recyclerview库(主页面的RecyclerView需要);
2、布局文件的根布局采用android.support.design.widget.CoordinatorLayout,因为design库的动态效果都依赖于该控件;
3、CoordinatorLayout节点要添加命名空间声明xmlns:app="http://schemas.android.com/apk/res-auto";
4、使用android.support.design.widget.AppBarLayout节点包裹Toobar;
5、Toobar节点添加滚动属性app:layout_scrollFlags="scroll|enterAlways",声明工具栏的滚动行为标志;
6、演示页面的主体页面使用RecyclerView控件,并给该控件节点添加行为属性app:layout_behavior="@string/appbar_scrolling_view_behavior",表示通知AppBarLayout捕捉RecyclerView的滚动操作。

下面是AppBarLayout结合RecyclerView实现的工具栏向上滚动效果截图:

下面是AppBarLayout结合RecyclerView的布局文件代码例子:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/cl_main"android:layout_width="match_parent"android:layout_height="match_parent" ><android.support.design.widget.AppBarLayoutandroid:id="@+id/abl_title"android:layout_width="match_parent"android:layout_height="wrap_content" ><android.support.v7.widget.Toolbarandroid:id="@+id/tl_title"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="@color/blue_light"app:layout_scrollFlags="scroll|enterAlways" /></android.support.design.widget.AppBarLayout><android.support.v7.widget.RecyclerViewandroid:id="@+id/rv_main"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior" /></android.support.design.widget.CoordinatorLayout>

嵌套滚动视图NestedScrollView

虽说通过AppBarLayout可实现Toolbar的滚动效果,但并非所有可滚动的控件都会触发Toolbar滚动,事实上只有Android5.0之后新增的少数滚动控件才具备该特技。RecyclerView是其中一个特工,它可用来替代ListView和GridView;替代ScrollView的则另有其人,它便是嵌套滚动视图NestedScrollView,在Android5.0之后的v4库中提供。

NestedScrollView继承自FrameLayout,其用法与ScrollView相似,如都必须且只能带一个直接子视图,都是允许视图上下滚动等等。NestedScrollView多出来的功能,也就是跟AppBarLayout配合使用,以便触发Toolbar的滚动行为,你可以把它当作是兼容了Android5.0新特性的增强版ScrollView。

下面是AppBarLayout结合NestedScrollView实现的工具栏向上滚动效果截图:

下面是AppBarLayout结合NestedScrollView的布局文件代码例子:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/cl_main"android:layout_width="match_parent"android:layout_height="match_parent" ><android.support.design.widget.AppBarLayoutandroid:id="@+id/abl_title"android:layout_width="match_parent"android:layout_height="wrap_content" ><android.support.v7.widget.Toolbarandroid:id="@+id/tl_title"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"app:layout_scrollFlags="scroll|enterAlways"android:background="@color/blue_light" /></android.support.design.widget.AppBarLayout><android.support.v4.widget.NestedScrollViewandroid:id="@+id/nsv_main"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_behavior="@string/appbar_scrolling_view_behavior" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical" ><TextViewandroid:layout_width="match_parent"android:layout_height="100dp"android:background="#ffaaaa"android:gravity="center"android:text="hello"android:textColor="#000000"android:textSize="17sp" /><TextViewandroid:layout_width="match_parent"android:layout_height="800dp"android:background="#aaffaa"android:gravity="center"android:text="world"android:textColor="#000000"android:textSize="17sp" /></LinearLayout></android.support.v4.widget.NestedScrollView></android.support.design.widget.CoordinatorLayout>

话说除了RecyclerView和NestedScrollView,还有哪些控件可以触发AppBarLayout的滚动行为呢?这还得从CoordinatorLayout说起,查看CoordinatorLayout的源代码,发现它实现了接口NestedScrollingParent,奥秘就在其中,该接口定义了嵌套滚动的父辈行为,与之对应的是定义了嵌套滚动的子辈行为接口NestedScrollingChild。凡是实现了接口NestedScrollingChild的控件,理论上都能够触发AppBarLayout去滚动。所以,搜遍Android的SDK源码,总共也只有三个控件符合这个条件,它们是RecyclerView、NestedScrollView,以及SwipeRefreshLayout,在布局文件中使用的名称如下所示:
RecyclerView : 使用名称android.support.v7.widget.RecyclerView
NestedScrollView : 使用名称android.support.v4.widget.NestedScrollView
SwipeRefreshLayout : 使用名称android.support.v4.widget.SwipeRefreshLayout

AppBarLayout的滚动标志

前面说到给Toobar节点添加滚动属性app:layout_scrollFlags="scroll|enterAlways",该属性其实来自于AppBarLayout,用来定义子控件具体的滚动行为,比如说是先滚还是后滚,是滚一半还是全部滚,是自动滚还是手动滚等等。

首先得弄清楚为什么AppBarLayout划分了这几种滚动行为,所谓知其然,还要知其所以然,才更有利于记忆和理解。
1、AppBarLayout的滚动依赖于主体视图的滚动,与主体视图相对应的,可将AppBarLayout称作头部视图。既然一个页面分为头部和主体两部分,那么就存在谁先滚谁后滚的问题了。
2、AppBarLayout内部的高度也可能变化,比如它嵌套了可折叠工具栏布局CollapsingToolbarLayout,有关可折叠工具栏布局的详细介绍参见《 Android开发笔记(一百三十六)可折叠工具栏布局CollapsingToolbarLayout》。既然AppBarLayout的高度是变化的,那也得区分是滚一半还是滚全部。
3、大家都知道ViewPager是左右滚动的翻页视图,用户通过手势把页面横向拉动一段距离后松开,系统会判断接下来是自动左滚还是自动右滚,总之最后用户看到的是一个完整的页面,而不是拉到一半的页面。同理,拉动AppBarLayout也有类似情况,当松开手指后,AppBarLayout得判断要不要继续向上收缩,或是继续向下展开。

区分好了各种滚动行为的起因与目的,然后再来谈谈layout_scrollFlags的标志位取值说明,具体的取值有五个说明如下:
1、scroll : 头部与主体一起滚动。scroll标志是基础标志,其他标志都要配合该标志使用;因为只有通过scroll声明Toolbar是可以滚动的,才有后面的各种各样滚动。
如果仅仅声明scroll,没有声明其它标志,则滚动效果如下图所示:

2、enterAlways : 头部与主体先一起滚动,头部滚到位后,主体继续向上或者向下滚。
同时声明scroll和enterAlways,滚动效果如下图所示:

后面三个标志都与CollapsingToolbarLayout有关,得配合该控件才能观察细节差异。所以本文只做下面三个标志的概念解释,有关的效果图参见《 Android开发笔记(一百三十六)可折叠工具栏布局CollapsingToolbarLayout》。

3、exitUntilCollapsed : 该标志保证页面上至少能看到最小化的工具栏,不会完全看不到工具栏。具体的滚动说明如下所示:
向上滚动:头部先往上收缩,一直滚到折叠的最小高度。然后头部固定不动,主体继续向上滚动。
向下滚动:头部固定不动,主体先向下滚动,一直滚到主体全部拉出。然后头部向下展开。

4、enterAlwaysCollapsed:该标志一般跟enterAlways一起使用,它与enterAlways区别在于有折叠操作,而单独的enterAlways没有折叠。具体的滚动说明如下所示:
向上滚动:头部先往上收缩,一直滚到折叠的最小高度。然后头部与主体先一起滚动,头部滚到位后,主体继续向上。
向下滚动:头部与主体先一起滚动,一直滚到头部折叠的最小高度。然后主体向下滚动,滚到位后头部继续向下展开。

5、snap : 在用户手指松开时,系统自行判断,接下来是全部向上滚到顶,还是全部向下展开。

点击下载本文用到的应用栏布局的工程代码

点此查看Android开发笔记的完整目录

Android开发笔记(一百三十五)应用栏布局AppBarLayout相关推荐

  1. Android开发笔记(三十五)页面布局视图

    布局视图的类别 布局视图有五类,分别是线性布局LinearLayout.相对布局RelativeLayout.框架布局FrameLayout.绝对布局AbsoluteLayout.表格布局TableL ...

  2. Android开发笔记(七十五)内存泄漏的处理

    内存泄漏的原因 一直以来以为只有C/C++才存在内存泄漏的问题,没想到拥有内存回收机制的Java也可能出现内存泄漏.C/C++存在指针的概念,程序中需要使用指针变量时,就从内存中开辟一块区域,并把该区 ...

  3. Android开发笔记(六十五)多样的菜单

    菜单Menu Android的菜单分为两类:选项菜单和上下文菜单,默认使用选项菜单.菜单的布局文件存放在res/menu目录下,使用ADT新建一个Android工程,首页代码MainActivity中 ...

  4. Android开发笔记(八十五)手机数据库Realm

    Realm应用背景 Android自带的SQLite数据库,在多数场合能够满足我们的需求,但随着app广泛使用,SQLite也暴露了几个不足之处: 1.开发者编码比较麻烦,而且还要求开发者具备SQL语 ...

  5. Android开发笔记(四十五)手势事件

    手势事件的流程 基本手势事件 基本的手势事件主要有如下三个方法: dispatchTouchEvent : 判断该事件是否需要下发.返回true表示需要下发给下级视图,返回false表示不需要下发(交 ...

  6. Android开发笔记(三十八)列表类视图

    AdapterView AdapterView顾名思义是适配器视图,Spinner.ListView和GridView都间接继承自AdapterView,这三个视图都存在多个元素并排展示的情况,所以需 ...

  7. Android开发笔记(三十六)展示类控件

    View/ViewGroup View是单个视图,所有的控件类都是从它派生出来:而ViewGroup是个视图组织,所有的布局视图类都是从它派生出来.由于View和ViewGroup是基类,因此很少会直 ...

  8. Android开发笔记(三十九)Activity的生命周期

    与生命周期有关的方法 下面是Activity类与生命周期有关的方法: onCreate : 创建页面 onStart : 开始页面 onStop : 停止页面 onResume : 恢复页面 onPa ...

  9. Android开发笔记(三十四)Excel文件的读写

    Android中操作Excel文件的场合较少见,主要是一些专业领域导入导出报表时使用,所以处理Excel读写的开源代码也很稀缺.目前读写Excel主要采用开源库jxl,这个是韩国人写的excel操作工 ...

  10. Android开发笔记(三十二)文件基础操作

    File类 File类是java中的文件操作工具类,它的常用方法如下: File构造函数 : 根据文件路径构造File对象 delete : 删除文件 exists : 判断文件是否存在 getNam ...

最新文章

  1. C#WinForm制作异形窗体/控件
  2. 最高3000元/人 , 助你成为C站红人 !
  3. 语言 全排列 函数_Power Query 中日期时间格式转换需要了解的区域语言对照表
  4. 学Java后未来发展方向和前景怎么样?
  5. 一篇文章教会你使用Python中三种简单的函
  6. 基于Matlab的跨孔CT胖射线追踪算法(三)
  7. Bootstrap补充
  8. 字节跳动面试必问:撸了大神写的spring源码笔记
  9. Android屏幕适配之--自定义像素的缩放比例来实现屏幕适配
  10. 计算机考研英语一和英语二的区别,2018考研英语一与英语二翻译有什么区别?怎么提高?...
  11. 考勤日历插件 android,jQuery手机考勤日历插件
  12. 《计算机技术领域当前的主流技术及其社会需求调查报告》
  13. RN5T5611用于车载品的可编程电源管理IC
  14. 手把手教你搭建高逼格监控平台,动起来吧
  15. 关于计算机软件的研究生就业,计算机软件与理论研究生毕业就业方向
  16. 每日一句_《鹧鸪天·西都作》
  17. CUDA之nvidia-smi命令详解
  18. MYSQL查询之查询的多个结果重复循环出现问题分析
  19. 精读《react-snippets - Router 源码》
  20. 关于SSD寿命问题的探讨

热门文章

  1. 面试准备每日系列:计算机底层之并发编程(二)缓存行、一致性协议、伪共享、disruptor、CAS等待
  2. 并行算法第五讲:Pthread编程
  3. 蓝桥杯 基础练习 回形取数
  4. 第十七:如何搭建Pytest+Allure2环境(重点非常详细)
  5. python和anaconda区别_Pycharm、Anaconda到底是什么?有什么区别?
  6. 4 5区别 angular 和_初探Angular的更新机制
  7. Java 表单提交下拉框_Java实现Layui的form表单动态绑定下拉框
  8. mysql修改失败,mysql修改数据失败(是我的代码有问题吗)怎么解决?
  9. dz mysql导出shell_mysql数据备份并导入数据库shell脚本
  10. 鸿蒙电视是无线么,鸿蒙系统首秀,在自家设备上和普通电视大不相同赵崇带你走世界...