Android 初识AppBarLayout 和 Coordin

作者: 亦枫 | 来源:发表于2016-08-17 14:36 被阅读11972次

    从这篇文章开始,和大家一起聊聊design包中的AppBarLayout和CoordinatorLayout。至此,Android Material Design系列的学习已进行到第四篇,大家可以点击以下链接查看之前的文章:

    AppBarLayout


    从名字上可以看出,AppBarLayout的设计精髓在于,与导航栏(也就是Toolbar)、顶部标签栏(即TabLayout)一起使用,来达到MD风格中App Bar的一些滚动交互设计效果。至于能实现哪些效果,在后文中我会举出几种常见的例子和实现方式。

    AppBarLayout.png

    从上图继承结构上可以看出,AppBarLayout从本质上就是一个垂直的LinearLayout,只是它为了实现交互动画效果增加了一些滑动特性,基本上严重依赖于协调者布局CoordinatorLayout。如果你将AppBarLayout放置在一个其它的ViewGroup中,这些滑动特性将不起作用,而此处的AppBarLayout也就是失去了原本存在的意义。

    定义在AppBarLayout中的Children应该明确设置各自的scrolling behavior,也就是滑动行为。在代码中,可以使用setScrollFlags(int)方法,在布局中可以使用app:layout_scrollFlags属性。setScrollFlags的参数取值是系统定义好的五个常量,位于AppBarLayout.LayoutParams类中。这五个常量的含义从名字中也可以看出一二,这里就不干巴巴的念叨了,后续结合着实际案例分别介绍,这样理解也会深刻一些:

    • SCROLL_FLAG_SCROLL
    • SCROLL_FLAG_EXIT_UNTIL_COLLAPSED
    • SCROLL_FLAG_ENTER_ALWAYS
    • SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED
    • SCROLL_FLAG_SNAP

    补充一点:可以使用addOnOffsetChangedListener方法为AppBarLayout添加滑动偏移监听事件,如:

    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
              // TODO
        }
    });
    

    verticalOffset 参数值表示偏移值,可用appBarLayout.getTotalScrollRange()方法获取最大偏移值。

    CoordinatorLayout


    协调者布局,Google将其解释为一个超级FrameLayout:

    CoordinatorLayout is a super-powered FrameLayout.

    CoordinatorLayout.png

    CoordinatorLayout存在的意义就是通过自定义Children的Behaviors(行为)来实现控件之间的交互动画效果。而像前文所提到的FloatingActionButton和AppBarLayout都有自己的DefaultBehavior(默认行为),所以,这两个控件更适合与CoordinatorLayout联合使用。当然,我们在使用CoordinatorLayout时,也可以自己动手编写Behavior来实现一些复杂的交互效果。

    CoordinatorLayout到底有多强大?接下来我会通过一些常见案例来一一展示它的使用,绝对让你看到过瘾,本文就先讲述FAB和Snackbar的例子。

    CoordinatorLayout 与 FAB 与 Snackbar


    在这个例子中,我们要实现这样一个效果,界面左下角又一个FloatingActionButton按钮,点击弹出Snackbar,效果图如下:

    FAB 01.gif

    只需要使用CoordinatorLayout和design包中FAB就能达到这个效果,布局代码如下:

    <?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.FloatingActionButton
            android:id="@+id/fab_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/dp_16"
            android:src="@mipmap/ic_toolbar_add"
            android:onClick="onClickFab"
            android:layout_gravity="end|bottom"
            app:backgroundTint="@color/fab_ripple"/>
    
    </android.support.design.widget.CoordinatorLayout>
    

    然后在代码中编写FAB的点击事件,弹出Snackbar,代码如下:

    public void onClickFab(View v){
            Snackbar.make(findViewById(R.id.fab_add), "Show The Snackbar", Snackbar.LENGTH_SHORT).show();
        }
    

    前面我们提过,android design包的FAB控件自带了默认的behavior,所以配合着CoordinatorLayout能够实现这个交互动画效果。如果你使用普通的Button控件取代FAB,或者其他的ViewGroup取代CoordinatorLayout,Snackbar显示时会遮挡住这个底部按钮,效果如下:

    FAB 02.gif

    使用这个例子必须特别强调两个问题,也是个人走过的坑,和大家分享一下, 避免你们和我走一样的弯路:

    • Snackbar.make参数问题
      前文我介绍Snackbar时提到了make方法的三个参数,特别是第一个View类型的参数,我使用了getWindow().getDecorView(),表示Snackbar展示的父窗口。在这个例子中,必须改为FAB对象或者CoordinatorLayout对象,否则Snackbar的出现还是会覆盖FAB,出现上图中的错误效果。

    • design包版本问题
      截止目前,design包已经更新到23.3.0版本了,一般我们都会使用最新版本的API,但是这个案例中如果你选择了最新版本,会出现另一种问题,Snackbar消失后,FAB按钮停留在上移的位置,不会向下移动回去,如图所示:

      FAB 03.gif
      而在23.1.0版本的design包中不存在这个问题,估计下个版本的design包会修复这个问题吧。所以,如果你也想实现这个效果,千万要记得不要使用目前最新版本23.3.0的design包,而是:
    compile 'com.android.support:design:23.1.0'
    

    示例源码


    我在GitHub上建立了一个Repository,用来存放整个Android Material Design系列控件的学习案例,会伴随着文章逐渐更新完善,欢迎大家补充交流,Star地址:

    https://github.com/Mike-bel/MDStudySamples

    相关文章

      网友评论

      • MonkiRayman:Mark一波
      • 0586b40de487:在网上找了不少代码,但实际应用中都发现很多都要21或以上支持效果,但我代码需支持14。
      • 0586b40de487:想问一下,这个代码最低api版本从多少开始呢。
      • 墨墨_2016:赞
        亦枫:@c51c33a8b8bc 谢谢:blush:
      • CalvinNing:技术鸟^_^,大赞一个
        亦枫:@CalvinNing :smile:
      • SundyXu:加一个AppBarLayout 的使用例子就更好了
        亦枫:@SundyXu 系列文章,已经发布了,可以关注我的公众号哈:smile:

      本文标题:Android 初识AppBarLayout 和 Coordin

      本文链接:https://www.haomeiwen.com/subject/mpdmsttx.html