CoordinatorLayout(1)

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

CoordinatorLayout is a super-powered FrameLayout.

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

1-SnackBar和FloatingActionButton交互:##

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

CoordinatorLayout(1)_第1张图片
Behavior实现类

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


Behavior抽象类

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

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

效果如图:


ToolBar随界面上滑而收缩隐藏

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

 

 


 app:layout_scrollFlags="scroll|enterAlways" 
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> 

 
 

 

  
app:layout_behavior="@string/appbar_scrolling_view_behavior" android:id="@+id/viewPager" 
android:layout_width="match_parent" android:layout_height="wrap_content"/> 


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

首先,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属性又使用此标志时,你的视图只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。通过这个示例图就明白了:
    CoordinatorLayout(1)_第2张图片
    ENTER_ALWAYS_COLLAPSED

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

  • EXIT_UNTIL_COLLAPSED:滑动的时候这个空间会收缩,并且最多只能收缩到minHeight如下图:[图片上传失败...(image-5f2127-1570814756946)]

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

同理,设置给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:
CoordinatorLayout(1)_第4张图片
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效果:##

CoordinatorLayout(1)_第5张图片
CollapsingToolbarLayout实现炫酷头部效果

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

3.2 布局文件:##

 

 
           


  

    
      app:layout_collapseMode="pin" 
      app:popupTheme="@style/Theme.AppCompat.Light" 
      app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> 

   
  

    
    app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

     
     
  

  
    app:layout_anchor="@id/appbar" 
    app:layout_anchorGravity="bottom|right|end"   
    android:src="@drawable/ic_done" android:layout_margin="20dp"   
    android:clickable="true"/>


这是一个全新的页面,和上面的栗子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,实现我们自己的布局交互动画效果感谢你能耐心看到这里~~

你可能感兴趣的:(CoordinatorLayout(1))