Material Design : 带动画的标题栏

原文地址:http://blog.grafixartist.com/toolbar-animation-with-android-design-support-library/

废话不多说,先看效果图:

Demo1

直接上代码,首先是app/build.gradle依赖:

1
2
3
4
5
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:design:25.1.0'
compile 'com.android.support:recyclerview-v7:25.1.0'
compile 'com.android.support:cardview-v7:25.1.0'
compile 'com.android.support:palette-v7:25.1.0'

依赖有个小技巧,可以看我的前面的文章。然后是layout文件,该效果主要部分还是布局,代码部分很少,打开activity的xml文件,大致框架如下:

1
2
3
4
5
6
7
8
9
10
11
12
<android.support.design.widget.CoordinatorLayout >

<android.support.design.widget.AppBarLayout >
<android.support.design.widget.CollapsingToolbarLayout >
<ImageView />
<android.support.v7.widget.Toolbar />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

<!-- 你的可滚动试图,比如RecyclerView -->

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

CoordinatorLayout

就是一个超级FrameLayout,定义了一系列的行为(behavior),与包裹着的子视图互动。允许悬浮的view以此为基准,固定。

AppBarLayout

本质上就是一个垂直的线性LinearLayout,根据子视图的滚动和CoordinatorLayout的联动。一般作为CoordinatorLayout的直接子视图。

CollapsingToolbarLayout

用来包裹Toolbar的,使图片收缩的时候让Toolbar适应标题的字体大小。鬼知道他们经历了什么!

好了,来看下具体的xml代码,警告!下面的代码有点长,建议上个厕所再回来看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<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:fitsSystemWindows="true">

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

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginBottom="32dp"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">

<ImageView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/header"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />

<android.support.v7.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:src="@mipmap/ic_action_add"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end" />

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

下面来解释下,CollapsingToolbarLayout的layout_scrollFlags属性:

  • scroll:用了这个属性表示可以滚动。我觉得就是废话。。。
  • exitUntilCollapsed:滚动退出屏幕直到它收缩起来的高度,就是最小高度,就是一般的Toolbar的高度,就不给滚了。

ImageView的layout_collapseMode属性值parallax我也说不清,看开头那个效果大概脑补下,然后自己百度去。

我们并没有给Toolbar设置背景颜色,这件任务我们交给CollapsingToolbarLayout动态的去选择图片上的一个颜色设置。

我们也没有给FAB(FloatingActionButton)设置大小,有默认值,不用设置,默认就是图中那么大,你可以用app:fabSize="mini"指定最小的尺寸。anchor属性就是固定在appbar的底部,右边,尾部。

下面就是一些代码部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
toolbar = (Toolbar) findViewById(R.id.anim_toolbar);
setSupportActionBar(toolbar);

collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle("Material Design");

ImageView imageView = (ImageView) findViewById(R.id.header);

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.header);
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
mutedColor = palette.getMutedColor(getResources().getColor(R.color.colorPrimary));
collapsingToolbar.setContentScrimColor(mutedColor);
}
});

recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new SimpleRecyclerViewAdapter(this));

CollapsingToolbarLayout的标题就是Toolbar的标题,然后我们使用Palette API获取图片的mutedColor,查阅api还可以获取几个其他的颜色,没事可以试试。还要注意下,你的app主题必须是’NoActionBar’,不然setSupportActionBar(toolbar)会报错。

大功告成,跑一下看看吧。附上 Github源代码。该代码比原作者的代码少了好多东西,尽量简单。不懂的可以问,反正我不一定会。嗯,顺便骗个star。