Android中的layout概念,Android开发之CoordinatorLayout详解

2.2.6用CoordinatorLayout实现Toolbar隐藏和折叠

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

1.CoordinatorLayout实现Toolbar隐藏效果

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

01786220eeb8654b7d20c5a43278fd13.png

bb5267a84b70999344671f789e5f0b83.png

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

9e085789a43badc9406dc1df1c7a1e99.png

0ed5181148a55f40f993428aee53d737.png

主界面的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节,这里就不赘述了。

685d64ce2f13ada39267276f51573453.png

图2-21默认展开的样式

ebb624ed48bddf3ca8f365a82e623901.png

图2-22向上滑动的样式

575fff8afacc934fbc9ae331b9321d5b.png

图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。布局文件代码如下所示:

ea221293017932af67e7f89fe49aae87.png

178ef7cfafc1aaf44f349b829412197b.png

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 {

ee916f901637e621ff745bdec8a7a701.png

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

6e9dd02533b50b40ba1711128adb480e.png

图2-24展开的CollapsingToolbarLayout

ce10d255a2e3c3f3b6f504603e698d7d.png

图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()方法。我们需要明确自己需要实现什么,也就是我们定义一个底部提示条,当我们向上滚动的时候其就消失,向下滚动时就出现。我们用第一种方法来实现,下面查看布局。

80d5daef96079f6064c4e0f5dc5762d1.png

41d48f4c0d7aa8610b8212b63626039c.png

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

54588c63cbe71819bc21a987c7b93bd2.png

自定义的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) {

d4f3a5ee1dbece5fc9ff8c9881cdee86.png

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

2a8887e71df75442a6cdbacf1552f8ec.png

图2-26自定义Behavior

ab741208b6c97e41221119c9f7bdd5da.png

我们重新定义了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,代码如下所示:

3efec1a62c1649479cc4adefb471dd04.png

运行程序,发现效果和第一种方法实现的效果不同,底部新加的 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,让设计师、产品经理更多地了解这些知识,对于我们开发者来说并没有坏处。

853f24a3de4e9f76e21c90aae0bc3ba6.png

作者:

喜欢围棋和编程。查看的所有文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值