Android开发之CoordinatorLayout详解

CoordinatorLayout是Android Design Support Library中比较难的控件。顾名思义,它是用来组织其子View之间协作的一个父 View。CoordinatorLayout默认情况下可被理解为一个FrameLayout,它的布局方式默认是一层一层叠上去的。

2.2.6用CoordinatorLayout实现Toolbar隐藏和折叠

CoordinatorLayout是Android Design    Support   Library中比较难的控件。顾名思义,它是用来组织其子View之间协作的一个父    View。CoordinatorLayout默认情况下可被理解为一个FrameLayout,它的布局方式默认是一层一层叠上去的,在此会介绍一下它最常用的两种情况。

1.CoordinatorLayout实现Toolbar隐藏效果

本节的例子仍旧是在2.2.4节代码的基础上进行修改的。我们仍旧从布局文件讲起,最外层我们用CoordinatorLayout示:来做整体的布局,AppBarLayout将Toolbar和TabLayout整合成了一个整体,代码如下所

能隐藏的关键是app:layout_scrollFlags=”scroll|enterAlways”这个属性,设置滚动事件,属性里面必须至少启用scroll这个flag,这样这个View才会滚动出屏幕,否则它将一直固定在顶部。接下来看看Java代码的引用,如下所示:

主界面的Java代码和2.2.4节的主界面代码并没有什么区别,我们运行程序,默认的效果如图2-21所示。当我们的手指向上滑动屏幕时,随着手指的滑动Toolbar会逐渐消失滑进屏幕上方,如图2-22所示。我们在这里还用到了上面讲到的Snackbar和FloatingActionButton,点击FloatingActionButton会触发      checkin()方法,这就会弹出Snackbar。至于为什么这里要用到FloatingActionButton和Snackbar,是因为FloatingActionButton和CoordinatorLayout结合起来用会有一个特殊的效果,如图2-23所示。当我们点击FloatingActionButton弹出Snackbar的时候,为了给  Snackbar留出空间,浮动的   FloatingActionButton会向上移动。这是因为配合CoordinatorLayout,FloatingActionButton有一个默认的    Behavior来检测Snackbar的添加并让按钮在Snackbar之上呈现上移与Snackbar等高的动画。关于Behavior属性,我们会在后面讲到。其他的代码请参照2.2.4节,这里就不赘述了。

图2-21默认展开的样式

图2-22向上滑动的样式

图2-23浮动的FloatingActionButton

2.CoordinatorLayout结合CollapsingToolbarLayout实现Toolbar折叠效果

要实现折叠效果,我们需要引入一个新的布局CollapsingToolbarLayout,其作用是提供一个可以折叠的Toolbar。CollapsingToolbarLayout继承自FrameLayout。CollapsingToolbarLayout设置layout_scrollFlag属性,可以控制包含在CollapsingToolbarLayout中的控件,比如mageView、Toolbar在响应    layout_behavior事件时做出相应的 scrollFlags滚动事件。在布局文件中用CollapsingToolbarLayout将    ImageView和   Toolbar包含起来作为一个可折叠的  Toolbar,再用AppBarLayout包裹起来作为一个Appbar的整体。当然,AppBarLayout目前必须是第一个嵌套在CoordinatorLayout里面的子View。布局文件代码如下所示:

CollapsingToolbarLayout有几个关键属性需要说明一下:

• app:contentScrim=””,用来设置CollapsingToolbarLayout收缩后最顶部的颜色。

•  app:expandedTitleGravity=”left|bottom”,表示将此CollapsingToolbarLayout完全展开后,title所处的位置,默认的值为left+bottom。

•app:collapsedTitleGravity=”left”,表示当头部的衬图ImageView消失后,此title将回归到Toolbar的位置,默认的值为left。

•app:layout_scrollFlags=””,这个属性我们上面讲过,它用来设置滚动事件,属性里面必须至少启用scroll这个flag,这样这个View才会滚动出屏幕,否则它将一直固定在顶部。这里我们设置的是app:layout_scrollFlags=”scroll|exitUntilCollapsed”,这样能实现折叠效果。如果想要隐藏效果,我们可以设置app:layout_scrollFlags=”scroll|enterAlways”。

我们需要定义AppBarLayout与滚动视图之间的联系,Design Support  Library包含了一个特殊的字符串资源@string/appbar_scrolling_view_behavior,它和AppBarLayout.ScrollingViewBehavior相匹配,用来通知需要设置在触发事件的View之上,所以我们应该在RecyclerView或者任意支持嵌套滚动的View比如NestedScrollView上添加 app:AppBarLayout何时发生了滚动事件。这个    Behaviorlayout_behavior=”@string/appbar_scrolling_view_behavior”这个属性。当然,AppBarLayout中的子   View需要设置 app:layout_scrollFlags这个属性;否则就算接收到RecyclerView滚动事件,AppBarLayout也不会有什么变化。接下来看看 Java代码的引用,代码如下所示:

public class CollapsingToolbarActivity extends AppCompatActivity {

这里列表的  Adapter还是用到了此前定义的   RecyclerViewAdapter,另外设置了CollapsingToolbarLayout的标题,其运行效果如图2-24所示。这个时候我们向上滑动,哆啦A梦的图片就会逐渐消失,哆啦A梦这个标题也会逐渐移动到左上方,最终效果如图2-25所示。

图2-24展开的CollapsingToolbarLayout

图2-25折叠的CollapsingToolbarLayout

3.自定义Behavior

CoordinatorLayou中最经典的设计就是Behavior,在前面我们提到了app:layout_behavior=”@string/appbar_scrolling_view_behavior”,其实@string/appbar_scrolling_view_behavior对应着的是AppBarLayout.ScrollingViewBehavior。我们也可以自定义Behavior来实现自己的组件和滑动交互。自定义Behavior可以分为两种方法:第一种是定义的View监听CoordinatorLayout里的滑动状态;第二种是定义的View监听另一个View的状态变化,例如View的大小、位置和显示状态等。对于第一种方法,我们需要注意onStartNestedScroll()和onNestedPreScroll方法;而对于第二种方法,则需要注意layoutDependsOn()和onDependentViewChanged()方法。我们需要明确自己需要实现什么,也就是我们定义一个底部提示条,当我们向上滚动的时候其就消失,向下滚动时就出现。我们用第一种方法来实现,下面查看布局。

我们在原有的布局基础上添加了一个LinearLayout,里面有一个TextView。需要注意的是我们在LinearLayout布局中添加了app:layout_behavior=”com.example.liuwangshu.mooncoordinatorlayout.FooterBehavior”这个属性,其中FooterBehavior就是我们自定义的Behavior,代码如下所示:

自定义的Behavior要继承CoordinatorLayout.Behavior<View>。父类Behavior中有很多方法,我们在这里只关心 onStartNestedScroll()和  onNestedPreScroll方法。onStartNestedScroll()方法的返回值表明这次滑动我们要不要关心,这里我们关心的是Y轴方向上的。onNestedPreScroll()方法则用于处理滑动。这个参数child就是我们定义的LinearLayout;dy则是我们水平滑动的距离,向上滑动为正值,向下滑动则为负值。如果滑动的距离累加值directionChange大于我们设置的LinearLayout的高度,并且该LinearLayout是VISIBLE状态,则隐藏LinearLayout。如果directionChange小于0,并且LinearLayout是GONE状态,则显示LinearLayout。显示和隐藏的代码如下所示:

private void hide(final View view) {

show()方法和    hide()方法用来展示显示和隐藏的动画。这里用到了属性动画,关于属性动画会在第3章进行讲解,在这里就不介绍了。在这里需要注意的就是在动画结束时,也就是回调方法onAnimationEnd(Animator animator)中对我们添加的 LinearLayout进行处理,show()方法在动画结束时调用view.setVisibility(View.VISIBLE),而hide()方法在动画结束时调用view.setVisibility(View.GONE)。运行程序来查看效果,如图2-26所示。默认情况下这个控件是显示出来的,我们向上滑动时它就会消失,而我们再次向下滑动的时候它又会显示出来。到此,自定义Behavior的第一种方法就讲到这里了。接下来讲第二种方法,那就是我们定义的LinearLayout去监听另一个View的状态变化。使用第二种方法重新自定义Behavior代码如下所示。

图2-26自定义Behavior

我们重新定义了FooterBehaviorAppBar继承CoordinatorLayout.Behavior<View>。我们前面提到第二种方法要关心layoutDependsOn()和onDependentViewChanged()方法。layoutDependsOn()方法用来返回我们需要关心的类,其第一个参数是当前的CoordinatorLayout,第二个参数child是我们设置这个Behavior的View,第三个参数dependency是我们关心的那个View。而我们在layoutDependsOn()方法中返回了dependency instanceof AppBarLayout,意思就是我们关心的那个View是AppBarLayout。onDependentViewChanged()方法根据我们关心的View的变化来对我们设置Behavior的View进行一系列处理。我们在这个方法中根据dependency(appBarLayout)的垂直移动距离来设定child(LinearLayout的)移动距离。接下来修改布局,将app:layout_behavior修改为我们重新设定的FooterBehaviorAppBar,代码如下所示:

运行程序,发现效果和第一种方法实现的效果不同,底部新加的 LinearLayout并不完全随着我们的手指滑动而变化,而是随着AppBarLayout的显示而显示,随着AppBarLayout的隐藏而隐藏。而 AppBarLayout的显示和隐藏又根据我们的手指滑动产生变化。所以我们定义的LinearLayout只有在滑到屏幕顶端的时候,会随着AppBarLayout的显示而逐渐显示出来。这个时候我们向上滑动,LinearLayout也随着AppBarLayout的隐藏而隐藏,其余的场景LinearLayout并不会随着我们手指的手势而产生变化。

2.3本章小结

本章主要介绍了Material Design的基本概念和Android Design  Support Library库中主要控件的使用方法。开发者也需要对设计工作有一些了解。目前国内遵循Material  Design的产品很少,很多设计师和产品经理也并不知道Android有自己的一套设计标准,他们更多的都是将iOS的设计风格硬搬到Android上,更有甚者就是想在多个平台下搞一套UI。所以推广Material  Design,让设计师、产品经理更多地了解这些知识,对于我们开发者来说并没有坏处。

作者:

喜欢围棋和编程。

 
发布于 分类 编程标签

发表评论

电子邮件地址不会被公开。