前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(一百三十五)应用栏布局AppBarLayout

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

作者头像
aqi00
发布2019-01-18 14:52:02
2K0
发布2019-01-18 14:52:02
举报
文章被收录于专栏:老欧说安卓

应用栏布局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的布局文件代码例子:

代码语言:javascript
复制
<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.AppBarLayout
        android:id="@+id/abl_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <android.support.v7.widget.Toolbar
            android: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.RecyclerView
        android: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的布局文件代码例子:

代码语言:javascript
复制
<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.AppBarLayout
        android:id="@+id/abl_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <android.support.v7.widget.Toolbar
            android: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.NestedScrollView
        android:id="@+id/nsv_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:background="#ffaaaa"
                android:gravity="center"
                android:text="hello"
                android:textColor="#000000"
                android:textSize="17sp" />

            <TextView
                android: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开发笔记的完整目录

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年02月22日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 应用栏布局AppBarLayout
  • 嵌套滚动视图NestedScrollView
  • AppBarLayout的滚动标志
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档