MaterialDesign系列文章(六)CoordinatorLayout的一些联动

4,004 阅读9分钟

今天在家偷了会懒,看了《铁甲钢拳》。强烈的推荐这部电影,谁说我们程序员不懂得生活的!!!站出来。你说对了。😭 这不由回来敲代码了吗。。。

一张铁甲钢拳镇楼

今天我们聊点什么呢?想了很久,觉得MaterialDesign最酷炫的莫过于顶部滑动的折叠效果了!(我这么觉得的)开始的时候我是抵触的,我们班主任(UI大大)跑过来说这个好看,你能实现吗?男人怎么能说不行呢。。。

然后我果断的说了一句“不会”。之后就没有之后了,被老大教训了一顿(别觉得我老大很凶,我老大只会腼腆的笑。我最怕的就是这个。。。),然后我就只好硬着头皮去弄了,其实我发现还是挺简单的!!!所以和大家分享一下。。。

本文知识点:

  • 所需要的属性分析
  • app:layout_scrollFlags属性的分析
  • CoordinatorLayout、AppBarLayout和TabLayout的联动
  • CoordinatorLayout、CollapsingToolbarLayout、AppBarLayout、FloatingActionButton和TabLayout的联动

1. 所需的属性分析

首先说一下CoordinatorLayout是什么?他就是个超级FrameLayout,但是由于内部维护了Behavior,所以可以处理内部控件的联动问题。里面的属性我会分控件进行说明的,你放心保证让你懂!

1.1 CoordinatorLayout的属性

  • android:layout_gravity 控制子控件位置的
  • app:layout_behavior 设置行营behavior的(可以自定义,也可以用系统的。最常用的就是@string/appbar_scrolling_view_behavior)设置滚动的联动
  • app:layout_scrollFlags 设置子控件的联动方式,后面详细讲解

1.2 AppBarLayout的属性

本来我是想先写完所有控件在来写这篇文章的,然后我觉得应该先让大家知道MaterialDesign能给我们带来什么,之后你才有学习的动力。所以这里就先简单的说一下属性标签吧!其实这里也就是配合显示一下,后面我会详细讲解的。

  • app:expanded AppBarLayout是否在开始的时候显示出来,true代表直接显示出来,false为不显示,但是你滑动的时候它就出来了!
  • android:elevation 设置阴影的,如果你觉得没有背景一定是你没有给它设置背景色,如果你没设置背景色是不会由阴影的。相信我。。。

1.3 ToolBar的属性

关于这个内容,希望你看看我之前写的MeterialDesign系列文章(一)ToolBar的使用里面应该很好的介绍了Toolbar的使用!这里就不啰嗦了!

1.4 TabLayout的属性

  • app:tabIndicatorColor 底条的颜色
  • app:tabSelectedTextColor 选择后的文字颜色
  • app:tabTextColor 默认的文字颜色
  • app:tabGravity 对齐方式
  • app:tabMode 模式,分为固定个数(fixed)和滚动模式(scrollable)

1.5 FloatingActionButton的属性

关于这个内容,希望你看看我之前写的MaterialDesign系列文章(四)FloatingActionButton的使用里面应该很好的介绍了Toolbar的使用!这里就不啰嗦了!

1.5 CollapsingToolbarLayout的属性

这个属性就比较多了。。。

  • app:collapsedTitleGravity 折叠状态的时候标题防止的位置,top、center等
  • app:collapsedTitleTextAppearance 折叠状态标题文字的样式
  • app:expandedTitleTextAppearance 展开状态标题文字的样式
  • app:contentScrim 折叠成Toolbaru宽度时候的颜色
  • app:expandedTitleGravity 展开时候标题如何放置
  • app:titleEnabled 指定是否显示标题文本
  • app:toolbarId 指定与之关联的ToolBar,如果未指定则默认使用第一个被发现的ToolBar子View
  • app:expandedTitleMarginXXX 展开状态改变标题文字的位置,通过margin设置
  • app:layout_collapseParallaxMultiplier 设置视差的系数,介于0.0-1.0之间
  • app:layout_collapseMode "parallax":固定模式,在折叠的时候最后固定在顶端;"pin":视差模式,在折叠的时候会有个视差折叠的效果

基本上以上控件的属性就这么多了,其实我建议大家有时间的时候去看看API文档,别说不懂英语,我英语3+的水平,真的。谷歌翻译什么都可以搞定的。其实有的方法我保证你不知道。

2. app:layout_scrollFlags的属性分析

首先我的表达可能不够贴切,介意大家去试试,在机器上跑一下就能清楚的记得了

  • scroll 滚动必须添加的属性
  • enterAlways 快速返回模式,当你每次向下滑的时候,设置该属性的控件会马上出来,然后在相应滚动事件。
  • enterAlwaysCollapsed 非快速返回模式,当你向下滑动的时候,设置该属性的控件不会先相应滚动事件,当滚动到头的时候才会响应滚动事件。但是如果你设置了minHeight的时候会先响应滚动事件,然后滚动到最小高度的位置,然后停止响应滚动事件,由滚动控件开始响应滚动事件,当滚动控件滚动到头的时候,然后在显示到最大高度
  • exitUntilCollapsed 和上面的类似,但不会滚动出屏幕,一直由最高高度那么高
  • snap 这个最简单的理解就是四舍五入。当设置该属性的控件显示一半以上的时候停止滚动,会全部显示出来,如果小于一般就害羞的回去了。

说了这么多估计你也不怎么理解,遂我从亦枫大神的博客中偷了几张图。如果觉得侵权什么的,立马删除!!!先说句谢谢。。。这里直接就帮大家科普一下一般情况下的设置了

  1. app:layout_scrollFlags="scroll|enterAlways"

scroll|enterAlways

  1. app:layout_scrollFlags="scroll|enterAlways

scroll|enterAlways

  1. app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"android:minHeight="50dp"

scroll|enterAlways|enterAlwaysCollapsed

  1. app:layout_scrollFlags="scroll|exitUntilCollapsed"android:minHeight="50dp"

scroll|exitUntilCollapsed

  1. app:layout_scrollFlags="scroll|snap"

scroll|snap

基本上涵盖了开发中的所有滚动的操作了。

3. CoordinatorLayout、AppBarLayout和TabLayout的联动

先看一下效果图

效果图一枚

实现这个效果是很简单的,要是在以前不得累死啊!又得监听滚动又得监听距离的,现在好了谢谢布局就搞定了。。。直接上布局吧!轻松实现。

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/abl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|snap|enterAlways"
            app:titleTextColor="@android:color/white">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="假装是一个标题"
                android:textColor="@android:color/white"
                android:textSize="18sp" />
        </android.support.v7.widget.Toolbar>

        <android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:tabSelectedTextColor="@color/colorAccent"
            app:tabTextColor="@android:color/white">

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="标签1" />

            <android.support.design.widget.TabItem
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="标签2" />
        </android.support.design.widget.TabLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:id="@+id/ll_bottom"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:gravity="center"
                android:text="底部还有内容啊!!!" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009988"
                android:gravity="center"
                android:text="标签1" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#002288"
                android:gravity="center"
                android:text="标签2" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009922"
                android:gravity="center"
                android:text="标签3" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#00aa88"
                android:gravity="center"
                android:text="标签4" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#999988"
                android:gravity="center"
                android:text="标签5" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

注意:

  • app:layout_behavior="@string/appbar_scrolling_view_behavior"这句是响应滚动的behavior,所有响应的滚动都使用这个
  • 所有的内容都要嵌套在AppbarLayout中,如果你单独对Toolbar设置app:layout_scrollFlags="scroll|snap|enterAlways"是没有用的!切记。。。
  • 大家仔细看一下,我的Toolbar是设置了app:layout_scrollFlags="scroll|snap|enterAlways"但是TabLayout是没有设置的,如果TabLayout要是也设置的话,那么TabLayout会和Toolbar一起滚动没了的!之前我在这块一直冲动的都设置了。所以效果你懂的。和你分享一下,怕有的小伙伴像我一样眼神不好使。。。

4. CoordinatorLayout、CollapsingToolbarLayout、AppBarLayout、FloatingActionnButton和TabLayout的联动

效果图一枚

这个直接上布局吧!或许我比较懒,但是我觉得还是为你好,你想啊,说了一堆都不如你看看,然后我给你讲来的实在。我这高度,懒都能说出如此的逼格。。。

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:theme="@style/AppBarTextStyle"
        android:layout_height="300dp">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:collapsedTitleGravity="center"
            app:contentScrim="@color/colorPrimary"
            app:expandedTitleGravity="bottom"
            app:layout_scrollFlags="scroll|snap|exitUntilCollapsed"
            app:title="假装这个一个标题"
            app:toolbarId="@id/toolbar">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:scaleType="fitXY"
                android:src="@mipmap/heard_2"
                app:layout_collapseMode="parallax" />

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

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

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:id="@+id/ll_bottom"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:gravity="center"
                android:text="底部还有内容啊!!!" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009988"
                android:gravity="center"
                android:text="标签1" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#002288"
                android:gravity="center"
                android:text="标签2" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009922"
                android:gravity="center"
                android:text="标签3" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#00aa88"
                android:gravity="center"
                android:text="标签4" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#999988"
                android:gravity="center"
                android:text="标签5" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:src="@mipmap/ic_call_white_24dp"
        app:layout_anchor="@id/appBar"
        app:layout_anchorGravity="end|bottom|right" />
</android.support.design.widget.CoordinatorLayout>

注意:

  • 所有内容都是包含在AppBarLayout中的,但是是对CollapsingToolbarLayout设置的app:layout_scrollFlags
  • Toolbar中有一个app:layout_collapseMode="pin"一定不要动,否则ToolBar会随着移动而消失,如果你想设置视差效果的话对ImageView进行设置就好了
  • android:theme="@style/AppBarTextStyle"设置了文字的颜色,代码是这样的
    <!--AppBarLayout的文字颜色-->
    <style name="AppBarTextStyle" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        <item name="android:textColor">@android:color/white</item>
    </style>

剩下的动你可以设置一下响应的属性看一下就可以了。

特别提醒:如果你的滚动内容里面包含RecyclerView的嵌套,也就是说NestedScrollView中嵌套了RecyclerView的话,你会发现,当你手指按到RecyclerView在滑动的时候,所有的响应都失效了。图片一直在那里不动了,这也是我们测试发现的。起初我觉得把RecyclerView的滚动事件禁了就好了,然后我发现并没有。。。后来找到了一个方法,在RecyclerView添加这句setNestedScrollingEnabled(false)就好了。等你用到的时候你会感谢我的。。。


今天分享的内容就这么多了。喜欢的话动动手指点一下喜欢,也不枉费我半夜写这篇文章。你的支持是我最大的动力!