什么是AppBarLayout
AppBarLayout继承自LinearLayout,子控件默认为竖直方向显示,可以用它实现Material Design的Toolbar;它支持滑动手势;它的子控件可以通过在代码里调用setScrollFlags(int)或者在XML里app:layout_scrollFlags来设置它的滑动手势。当然实现这些的前提是它的根布局必须是CoordinatorLayout。这里的滑动手势可以理解为:当某个可滚动View的滚动手势发生变化时,AppBarLayout内部的子View实现某种动作。
AppBarLayout的子控件不仅仅可以设置为Toolbar,也可以包含其他的View。
上面提到使用AppBarLayout的前提是它的根布局必须是CoordinatorLayout,所以我们得先认识一下CoordinatorLayout。
CoordinatorLayout
Google官网对CoordinatorLayout的介绍:
CoordinatorLayout is a super-powered FrameLayout.
CoordinatorLayout is intended for two primary use cases:
As a top-level application decor or chrome layout
As a container for a specific interaction with one or more child views
由上述的介绍可以知道,CoordinatorLayout继承自ViewGroup,作为一个应用顶层的装饰布局,也就是一个Activity Layout 的最外一层布局;作为一个或多个有特定响应动作的容器;协调(Coordinate)其他组件, 实现联动。
如何使用AppBarLayout
先看下效果:
可以看到,当向上滚动时,Toolbar移出屏幕,向下滑动时,Toolbar进入屏幕。这就是之前的说的滑动手势。
下面我们来具体看看它的使用,这是布局文件中的代码:
<?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" 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:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:title="特战先驱" app:titleTextColor="@android:color/white" /> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/intro"/> </android.support.v4.widget.NestedScrollView></android.support.design.widget.CoordinatorLayout>
上面的代码中,Toolbar指定了scrollFlags属性,这个属性设置Toolbar在滚动后所做的操作,有以下几个值可选:
| Scroll Flag | 作用 |
| ------------- |:-------------:|
| scroll | 子View如果设置layout_scrollFlags属性的值为scroll,这个View会随着Scrolling View一起滚动,当向上滚动的时候,Toolbar会滚出屏幕外,如果不设置,那么Toolbar会固定不动。 |
| enterAlways | 使用这个flag,当Scrolling View 向下滑动时,子View 将直接向下滑动,而不管Scrolling View 是否在滑动。注意:要与scroll 搭配使用,否则是不能滑动的。(上图演示的效果,正是scroll和enterAlways两个flag同时使用产生的效果,即向上滚动,Toolbar滚出屏幕,向下滚动,Toolbar重新进入屏幕)。 |
| enterAlwaysCollapsed | enterAlwaysCollapsed 是对enterAlways 的补充,当Scrolling View 向下滑动的时候,滑动View(也就是设置了enterAlwaysCollapsed 的View)下滑至折叠的高度,当Scrolling View 到达滑动范围的结束值的时候,滑动View剩下的部分开始滑动。这个折叠的高度是通过View的minimum height (最小高度)指定的。(要配合scroll|enterAlways 一起使用)|
|exitUntilCollapsed|当Scrolling View 滑出屏幕时(也就时向上滑动时),滑动View先响应滑动事件,滑动至折叠高度,也就是通过minimum height 设置的最小高度后,就固定不动了,再把滑动事件交给 Scrolling view 继续滑动。
|snap|在滚动结束后,如果view只是部分可见,它将滑动到最近的边界。比如,如果view的底部只有25%可见,它将滚动离开屏幕,而如果底部有75%可见,它将滚动到完全显示。
下面演示设置scrollFlags为 scroll | enterAlways | enterAlwaysCollapsed 的效果:
修改布局文件:
<?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" 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:layout_width="match_parent" android:layout_height="140dp" android:background="@color/colorPrimary" app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" app:title="特战先驱" app:titleTextColor="@android:color/white" /> </android.support.design.widget.AppBarLayout> ...</android.support.design.widget.CoordinatorLayout>
效果如下:
将Toolbar的高度设置为某个固定高度,这里设置为140dp,设置,由上图我们可以看到,当向上滚动的时候,Toolbar滚出屏幕,当向下滚动的时候,Toolbar进入屏幕,显示折叠高度(最小高度),当Scrolling View滚动到顶部的时候,AppBarLayout慢慢展开到原来的高度。
设置scrollFlags为scroll|exitUntilCollapsed,修改布局代码:
<?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" 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:layout_width="match_parent" android:layout_height="140dp" android:background="@color/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:title="特战先驱" app:titleTextColor="@android:color/white" /> </android.support.design.widget.AppBarLayout> ...</android.support.design.widget.CoordinatorLayout>
演示效果:
可以看到,向上滚动时,Toolbar随着滚动,但是不会完全滚出屏幕,而是到达折叠高度(最小高度),然后一直保持,当向下滚动的时候,Scrolling View一直滚动,当Scrolling View滚动到顶部时,ToolBar开始滚动,知道展开到原来的高度。
设置scrollFlags为scroll|snap,修改布局代码:
<?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" 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:layout_width="match_parent" android:layout_height="140dp" android:background="@color/colorPrimary" app:layout_scrollFlags="scroll|snap" app:title="特战先驱" app:titleTextColor="@android:color/white" /> </android.support.design.widget.AppBarLayout> ...</android.support.design.widget.CoordinatorLayout>
演示效果:
可以看到,当Toolbar展示部分的较大时,此时放手,它会自动将整个都展示出来;如果向下拉出一小部分,此时松手,它会自动将该部分收回去,这和上面说到snap的定义一致,滑动到最近的边界。
CollapsingToolbarLayout
学习了AppBarLayout和CoordinatorLayout,此时需要提到一个非常有用而且高大上的控件CollapsingToolbarLayout,由它的名字我们可以知道,它是一个折叠的Toolbar布局,先看下演示效果吧:
如何使用CollapsingToolbarLayout呢?只需要将Toolbar使用CollapsingToolbarLayout包裹起来,并且添加多一个展示背景图片的ImageView即可,如下是布局文件的代码:
<?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" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="250dp"> <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@mipmap/book"/> <android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:title="特战先驱" app:titleTextColor="@android:color/white" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> ...</android.support.design.widget.CoordinatorLayout>
其中layout_scrollFlags设置在CollapsingToolbarLayout上而不再是Toolbar上,并且设置为scroll|exitUntilCollapsed,当向上滚动到折叠高度时,会一直保持。
修改展开和折叠时文字的大小和字体
CollapsingToolbarLayout支持对展开时标题和折叠时标题的文字样式进行修改。
需要在style.xml定义样式:
<!--CollapsingToolbarLayout展开时标题文字样式--><style name="ExpandedTitleTextStyle" parent="TextAppearance.AppCompat.Title"> <item name="android:textSize">30sp</item> <item name="android:textColor">#fff</item></style><!--CollapsingToolbarLayout折叠时标题文字样式--><style name="CollapsedTitleTextStyle" parent="TextAppearance.AppCompat.Title"> <item name="android:textSize">16sp</item> <item name="android:textColor">#f00</item></style>
指定CollapsingToolbarLayout折叠和展开的标题样式:
<android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:collapsedTitleTextAppearance="@style/CollapsedTitleTextStyle" app:expandedTitleTextAppearance="@style/ExpandedTitleTextStyle" > ... </android.support.design.widget.CollapsingToolbarLayout>
修改后,效果如下:
到此为止,关于AppBarLayout、CoordinatorLayout和CollapsingToolbarLayout的使用,我们就基本掌握了。需要源码的可以查看: