Iwfu-CoordinatorLayout(1)

承接前几天的博客:

下面博客内容可能要有以下预备知识,你也可了解完这一篇内容以后再回过头看这些:

ToolBar使用:http://blog.csdn.net/rosechan/article/details/51511376
SnackBar&&FloatingActionButton:http://blog.csdn.net/rosechan/article/details/51520325
NavigationView:http://blog.csdn.net/rosechan/article/details/51534797
TabLayout:http://blog.csdn.net/rosechan/article/details/51568130

本文带来实现MaterialDesign中最重要的一个布局,CoordinatorLayout-协调布局,人如其名,这个布局主要用于协调内部的各个子控件进行交互,通过设置子控件的behavior(下面会讲到)来操控子控件的一些操作和动画,孔子曾经说过:

CoordinatorLayout is a super-powered FrameLayout.

以下面几个例子来说明CoordinatorLayout的基本使用:

1-SnackBar和FloatingActionButton交互:

在前几天的博客中讲到了这个,效果如下:
这里写图片描述

FAB随着SnackBar的出现和消失而上下滑动。这篇博客讲到了将FAB放在CoordinatorLayout布局中,再将SnackBar.make()的第一个参数传入CoordinatorLayout对象即可。那么为什么将FAB放在CoordinatorLayout中就让其发生改变呢,咋们从源码看起,我们可以在FloatingActionButton源码中看到有一个Behavior实现类:
这里写图片描述

从注释就可以看到,这个Behavior类会在FAB实例化时创建,其主要的功能就是让FAB与SnackBar交互,防止SnackBar遮挡FAB。
而在CoordinatorLayout中就包含了这个Behavior抽象类,并使用这个Behavior类来操纵内部空间的行为:
这里写图片描述

这也就是为什么FAB外面简单套一层CoordinatorLayout就会有交互效果的原因 ~

2-ToolBar随界面上滑而收缩隐藏

效果如图:

这里写图片描述

可以看到Toolbar随着内容部分的滑动产生了收缩隐藏,要实现这个效果,只需要修改xml文件,添加一些属性:

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

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

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/colorPrimary"
                <!--就是↓这个--> 
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>


            <android.support.design.widget.TabLayout
                android:id="@+id/tabLayout"
                app:tabIndicatorColor="#ffffff"
                app:tabSelectedTextColor="#ffffff"
                app:tabTextColor="#cdcdcd"
                app:tabGravity="center"
                app:tabMode="scrollable"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
            </android.support.design.widget.TabLayout>

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

        <android.support.v4.view.ViewPager
            <!--在这里↓-->            
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </android.support.design.widget.CoordinatorLayout>

里面涉及到之前博客的遗漏内容,一个个解析下。

首先,AppBarLayout是什么鬼,为什么要拿他包裹ToolBar和TabLayout,咋们再看源码发现,AppBarLayout中也有一个内置的Behavior类,而ToolBar和TabLayout中没有,所以我们可以得出,正因为AppBarLayout有Behavior,才能与CoordinatorLayout产生交互,由此我们可以推断AppBarLayout正是为了让协调布局和更早的toolbar之类的布局可以兼容工作才产生的。而仅仅使用AppBarLayout包裹toolbar和tablayout还不够,google亲爹说了:

Children should provide their desired scrolling behavior through setScrollFlags(int) and the associated layout xml attribute: app:layout_scrollFlags.

意思说AppBarLayout的子控件还要设置layout_scrollFlags属性(或者通过setScrollFlags( ))才能达到其想要的滑动行为效果。

所以我们在ToolBar标签里加上一句:

app:layout_scrollFlags="scroll|enterAlways"

就可以实现如图的效果~这里注意命名空间为app,在AndroidStudio会自动设置为res-auto,Eclipse玩家要自己设置命名空间了。

那么这个layout_scrollFlags里面属性值到底是啥?
通过提示我们可以看到有五种flag值:

2.1 五种FLAG:

  • SCROLL_FLAG_ENTER_ALWAYS
  • SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED
  • SCROLL_FLAG_EXIT_UNTIL_COLLAPSED
  • SCROLL_FLAG_SCROLL
  • SCROLL_FLAG_SNAP

这五种值分别对应的是AppBarLayout里控件的五种行为方式,如下~

  • FLAG_SCROLL:这个是其他控件想要有滑动隐藏行为的基础,下面的其他属性值,一定要设置了scroll后才有效果,所以设置属性要像这样~

    app:layout_scrollFlags=”scroll|enterAlways”

  • ENTER_ALWAYS: 当屏幕下滑,设置了这个行为的控件(比如toolbar)就会立马滑回屏幕,类似于快速返回的效果,而且不管下面的滑动组件(比如ScrollView是否正在滑动).

  • ENTER_ALWAYS_COLLAPSED: 当你的视图已经设置minHeight属性又使用此标志时,你的视图只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。通过这个示例图就明白了:

    这里写图片描述

可以看到toolbar设置了minHeight属性为10dp,看到toolbar向上偏移了10dp,所以进入时toolbar其实只进入了10dp,且下拉过程中,只有当滑到顶了,此时继续滑toolbar才会显示出来(对比上面enterAlways~)。

  • EXIT_UNTIL_COLLAPSED:滑动的时候这个空间会收缩,并且最多只能收缩到minHeight如下图:
    这里写图片描述

  • SNAP: 这个属性让控件变得有弹性,如果控件(比如toolbar)显示了75%的高度,就会弹出显示出来,如果只有25%显示,就会收缩隐藏起来,如图所示。

    这里写图片描述

同理,设置给tabLayout也有效果,所以使用这五种效果可以很好的配合CoordinatorLayout实现各种效果~

2.2设置layout_behavior属性

写到这里我才想到本来这个应该放前面写的,不过影响不大。如果你是照着上面一步步边敲边实践的,那么会踩到一个坑,CoordinatorLayout里的布局会被toolBar或者AppBarLayout挡住~

解决方法:在CoordinatorLayout中的可滑动布局添加(比如Viewpager中添加下面的标签,注意命名空间):

app:layout_behavior="@string/appbar_scrolling_view_behavior"

看到这里已经很熟悉了,behavior你穿上马甲我也认识你!又是一个不和协调布局兼容的控件,所以要加上这个属性,才能和协调布局中的其他组件配合,而传入的值呢,这么长一串是啥,根据刚刚查看Behavior源码我们知道,CoordinatorLayout是根据传入的Behavior行为的类名,利用反射来实例化行为对象,那么同样的,这里这么长一串也是一种行为,来自于AppBarLayout.ScrollingViewBehavior:

这里写图片描述

查看这个类的源码:

/**
     * Behavior which should be used by {@link View}s which can scroll vertically and support
     * nested scrolling to automatically scroll any {@link AppBarLayout} siblings.
     */
    public static class ScrollingViewBehavior extends HeaderScrollingViewBehavior {
    .....
    }

注释正是说这个Behavior可以让其他滑动控件可以与之兼容工作!(~搞到这里有一种悬疑片解谜的感觉了 ~(≧▽≦)/~,一切都是以CoordinatorLayout为核心,而真正的罪犯又来自Behavior,这个幕后主使才是操控一切子控件行为的根源~)

Tips:

到这里你也知道了 CoordinatorLayout不能和很多控件使用,比如要是内容部分放ListView,就算设置了layout_behavior也没用,取而代之使用RecyclerView或者NestedScrollView,在上例的内容如果使用ViewPager的话,ViewPager的子布局应使用NestedScrollView代替ScrollView才能保证可以滑动。

2.3综上所述:

为了使得Toolbar有滑动效果,必须做到如下三点:
1. CoordinatorLayout作为布局的父布局容器。
2. 给需要滑动的组件设置 app:layout_scrollFlags=”scroll|enterAlways” 属性。
3. 给滑动的组件设置app:layout_behavior属性

3-使用CollapsingToolbarLayout实现炫酷头部效果~

3.1效果:

这里写图片描述

很美,很华丽,很动人。节省时间,直接先上用法:

3.2 布局文件:

<?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"
    tools:context="com.chan.iwfu_md_news.activity.NewsDetailActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <!--关键在这里↓-->   
        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:collapsedTitleGravity="center"
            app:contentScrim="@color/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/iv_news_detail"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@mipmap/shibai"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.5"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar_newsDetail"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="#00000000"
                <!--关键在这里↓--> 
                app:layout_collapseMode="pin"
                app:popupTheme="@style/Theme.AppCompat.Light"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

        </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:padding="12dp"
         <!--关键在这里↓-->  
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <WebView
            android:id="@+id/webView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </WebView>


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

 <android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
         <!--关键在这里↓-->   
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/ic_done"
        android:layout_margin="20dp"
        android:clickable="true"/>

</android.support.design.widget.CoordinatorLayout>

这是一个全新的页面,和上面的栗子2没有多大关系,不过以后也可以是由首页跳转到这个界面来显示详情。在这个布局文件里,主要使用到了:

CollapsingToolbarLayout ,NestedScrollView这两个新东西,

查api:
- collaspsingToolbarLayout:是toolbar的包装类,继承了collapsing app bar,被设计直接作为AppBarLayout的子布局使用,以后也推荐用AppBarLayout-CollapsingToobarLayout-Toolbar这样的结构使用,

3.3 CollapsingToolbarLayout 提供以下属性和方法使用:

  1. Collapsing title:ToolBar的标题,当CollapsingToolbarLayout全屏没有折叠时,title显示的是大字体,在折叠的过程中,title不断变小到一定大小的效果。你可以调用setTitle(CharSequence)方法设置title。

  2. Content scrim:ToolBar被折叠到顶部固定时候的背景,你可以调用setContentScrim(Drawable)方法改变背景或者 在属性中使用 app:contentScrim=”?attr/colorPrimary”来改变背景。

  3. Status bar scrim:状态栏的背景,调用方法setStatusBarScrim(Drawable)。即实现沉浸状态栏(或者叫透明状态栏吧~不懂具体叫啥),貌似5.0以上才有效果。

  4. Parallax scrolling children:CollapsingToolbarLayout滑动时,子视图的视觉差,可以通过属性app:layout_collapseParallaxMultiplier=”0.6”改变。值de的范围[0.0,1.0],值越大视察越大。

  5. CollapseMode :子视图的折叠模式,在子视图设置,有两种“pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。我们可以在布局中使用属性app:layout_collapseMode=”parallax”来改变。

在布局文件collapsingToolbarLayout中使用ImageView作为背景图,设置上面的一些属性,就可以达到我们要的这种华丽的效果。

3.4 NestedScrollView:

就像scrollView,不过相比之下他更兼容新老版本的控件,更好的与后面的控件包括CoordinatorLayout配合使用.

3.5 FAB设置:

CoordinatorLayout提供app:layout_anchor,可以设置子视图的锚点,一般和layout_anchorGravity联用,这样这个组件就有悬浮于锚点布局的感觉了。并且会随着锚点布局而改变(如本例的AppBarLayout和FAB)。

app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"

Tip:

关于视差童鞋们自己试一试,这个不好用语言描述,不过对比一下还是会很有感觉的。

最后:

这篇到此就结束了,主要讲述了CoordinatorLayout协调布局这个MD风格控件的中流砥柱的作用,码字不易,明天再来一篇关于自定义Behavior,实现我们自己的布局交互动画效果~

感谢你能耐心看到这里~~~

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值