前言
2015年IO大会上,Google带来了Android M,同时还有Android支持库的新一轮更新,其中更是增加一个全新的支持库Android Design Support Library,包含了数个重要的Material Design组件,如CoordinatorLayout、TabLayout、NavigationLayout等,用于将Material Design适配到Android 2.1(API 7)。
首先,我们看看通过CoordinatorLayout来实现仿知乎的动画效果,接着我们会分布解析实现的原理:
CoordinatorLayout
在Material Design组件钟,CoordinatorLayout十分重要,任何酷炫效果的基础均源于它。首先看看官方对它的介绍。
CoordinatorLayout is a super-powered FrameLayout
CoordinatorLayout is intended for two primary use cases:
1. As a top-level application decor or chrome layout
2. As a container for a specific interaction with one or more child views
By specifying Behaviors for child views of a CoordinatorLayout you can provide many different interactions within a single parent and those views can also interact with one another. View classes can specify a default behavior when used as a child of a CoordinatorLayout using the DefaultBehavior annotation.
Behaviors may be used to implement a variety of interactions and additional layout modifications ranging from sliding drawers and panels to swipe-dismissable elements and buttons that stick to other elements as they move and animate.
Children of a CoordinatorLayout may have an anchor . This view id must correspond to an arbitrary descendant of the CoordinatorLayout, but it may not be the anchored child itself or a descendant of the anchored child. This can be used to place floating views relative to other arbitrary content panes.
Children can specify insetEdge to describe how the view insets the CoordinatorLayout. Any child views which are set to dodge the same inset edges by dodgeInsetEdges will be moved appropriately so that the views do not overlap.
从官方文档中,我们可以总结出以下几点
1. CoordinatorLayout 是一个功能强大的FrameLayout
2. CoordinatorLayout 的主要作用是协调各个子view之间的相互作用,而这些相互作用的实现主要依赖于它的一个内部类Behavior,下文中将会仔细分析这个类。
在日常使用中CoordinatorLayout 主要有三种常见的用法
1. 与FloatingActionButton的结合
2. 与TabLayout的结合
3. 与CollapsingLayout的结合
与FloatingActionButton的结合
与FloatingActionButton结合使用较为简单,只需要把两个控件在同一个页面布局在一起,不需要做任何特殊处理,这里就不做介绍了。
与TabLayout的结合
CoordinatorLayout 能够实现这种效果主要归功于AppbarLayout
- AppbarLayout
老规矩,先看源码
AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures.
Children should provide their desired scrolling behavior through setScrollFlags(int) and the associated layout xml attribute:app:layout_scrollFlags.
This view depends heavily on being used as a direct child within a CoordinatorLayout
If you use AppBarLayout within a different ViewGroup, most of it’s functionality will not work.
AppBarLayout also requires a separate scrolling sibling in order to know when to scroll. The binding is done through the AppBarLayout.ScrollingViewBehavior
behavior class, meaning that you should set your scrolling view’s behavior to be an instance of AppBarLayout.ScrollingViewBehavior. A string resource containing the full class name is available.
通过官方文档的介绍,我们能知道一下几点
1、AppBarLayout 是一个垂直方向的LinearLayout,用它来实现一种滚动效果
2、AppBarLayout 的子view要想实现滚动效果就必须要设置app:layout_scrollFlags这个属性
3、AppBarLayout下面需要设置一个有滚动效果的空间才能实现滚动的效果,如NestedScrollView,然后在这个控件中设置
app:layout_behavior="@string/appbar_scrolling_view_behavior
4、需要注意的是AppBarLayout 只能作为CoordinatorLayout的直接子view才能实现效果
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jcj.royalni.jcjzhihudaily.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/index_app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways">
<ImageView
android:id="@+id/live"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="5dp"
android:src="@drawable/live_button" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_toLeftOf="@id/live"
android:background=