天天看点

【Material Design】CoordinatorLayout使用介绍

一、CoordinatorLayout简介

CoordinatorLayout是Material Design 的重要组件,它作为父布局使用,可以协调(coordinate)其子布局,实现多种联动滚动效果。本文代码参考cheesesquare

二、基本结构

对cheesesquare中的布局代码进行了一些修改,把几种布局放到同一个界面上。

<?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"
    android:fitsSystemWindows="true"
    tools:context="com.quickframe.ui.MainDrawerActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/detail_backdrop_height"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="250dp"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlwaysCollapsed|snap"
            android:minHeight="50dp"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">
            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                android:src="@mipmap/ori"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"/>

            <!--app:layout_scrollFlags="scroll|enterAlways|snap"-->
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="@dimen/toolbar_height"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="@dimen/toolbar_height"
            app:tabMode="fixed"
            app:tabIndicatorHeight="@dimen/indicator_height"
            android:background="@color/white"
            app:tabIndicatorColor="@color/black"
            app:tabSelectedTextColor="@color/black"
            app:tabTextColor="@color/grey"/>

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

    <include
        layout="@layout/content_main_drawer"
        android:visibility="gone"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:backgroundTint="@color/grey"
        app:rippleColor="#33728dff"
        app:srcCompat="@android:drawable/ic_dialog_email"/>

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

如果对布局代码感觉混乱或者初次接触CoordinateLayout的话,可以看下结构图

【Material Design】CoordinatorLayout使用介绍

红框CoordinateLayout 父布局, 其中包含两部分:滚动视图和响应滚动视图

绿框ViewPager ViewPager也可换成其它布局如FrameLayout, 重点是此布局内必须有支持嵌套滚动的view, 如RecyclerView,NestedScrollView, 目前ListView不支持嵌套滚动。

蓝框AppBarLayout 响应滚动的容器布局, 当绿框中的视图滚动时,让AppBarLayout也产生滚动。可在其中写入多个子view,对每个子view定义各自的响应滚动属性,

紫框CollapsingToolbarLayout 作为AppBarLayout的子view之一,响应滚动,可折叠版的ToolBar, 可加入各种子控件如imageView, ToolBar等

灰框TabLayout AppBarLayout的子view之一, 配合ViewPager使用。

所以,CoordinateLayout主要包含了 滚动视图 和 响应滚动视图

三、滚动视图

在滚动视图ViewPager中,有一行代码

这里定义了滚动视图与响应滚动视图AppBarLayout之间的联系。在定义了layout_behavior后,CoordinateLayout就会搜索其子view,看是否有view和这下behavior相关联。查看appbar_scrolling_view_behavior的相关信息,可以看到

<string name="appbar_scrolling_view_behavior" translatable="false">android.support.design.widget.AppBarLayout$ScrollingViewBehavior</string>
           

它其实是AppBarLayout中的一个类ScrollingViewBehavior, 实现了滚动视图与AppBarLayout之间的联合滚动

也就是说,我们在滚动视图中通过layout_behavior定义一个行为behavior,作为滚动视图与响应滚动视图之间的联系,就可以实现各种联动效果,更进一步的话,可以自定义Behavior。

四、CollapsingToolbarLayout

AppBarLayout继承自LinearLayout,布局方式为垂直,在这里可以把它当成LinearLayout,只是它可以让它的子view实现响应滚动。在AppBarLayout里我们可以通过app:layout_scrollFlags 给它的子view设置动作属性, 上面的代码中,CollapsingToolbarLayout作为AppBarLayout的一个子view。

先来看下scrollFlags可以设置哪些动作,它的几个动作可以配合使用。

1. scroll: 子view如果想要滑出屏幕外,就必须设置这个flag,如果没有设置,那子view就只能停留在屏幕顶部。

2. enterAlways: 字面翻译 “总是进入”,子view设置了这个动作属性后,只要有任意的下滑动作,就可以让子view马上出现

3. enterAlwaysCollapsed: 字面意思是”总是折叠进入”,是enterAlways的扩展型,需要和enterAlways一起配合使用。这个属性一般要同时设置最小高度android:minHeight=”50dp”,也就是其折叠状态的高度,如果在CollapsingToolbarLayout里加了Toolbar同时设置了其高度的话,不用加上minHeight也可以实现这个属性动作的效果。当有下滑动作时,子view会以最小高度即折叠状态出现; 当继续下滑,直到滚动视图不能再滚动时,子view才会开始展开。

4. exitUntilCollapsed: 向上收缩视图,达到最小高度时,就会消失。当CollapsingToolbarLayout中有Toolbar时,可以使Toolbar保持在最顶部。

5. snap: 23.1.0的Desing Support Library新加了snap属性,在滚动结束时,如果view只有部分可见,就会自动滚动到最近的边界,确保了滚动不会在中间状态的时候停止。

实际情况如图

【Material Design】CoordinatorLayout使用介绍
【Material Design】CoordinatorLayout使用介绍
【Material Design】CoordinatorLayout使用介绍

CollapsingToolbarLayout是一种可折叠式的Toolbar,继承自FrameLayout,在其中可以加入Toolbar,ImageView等各种控件,给CollapsingToolbarLayout设置了layout_scrollFlags,它就可以对其中的控件的响应滚动事件进行控件,它可以设置的属性如下。

app:collapsedTitleGravity 折叠状态时标题的放置布局,可以设为top, bottom, right, left, center, fill_vertical, start等。

app:expandedTitleGravity 展开状态时标题的放置布局,设置同上。

app:collapsedTitleTextAppearance 折叠状态时标题的样式,可以通过style进行设置。

app:expandedTitleTextAppearance 展开状态时标题的样式。

app:contentScrim=”?attr/colorPrimaryDark” 折叠时的背景,当Toolbar保留在顶部时,可以通过该属性设置Toolbar的背景,

app:expandedTitleMarginStart

app:expandedTitleMargin

app:expandedTitleMarginBottom

app:expandedTitleMarginEnd 展开状态时标题的Margin

对于CollapsingToolbarLayout其中的控件,可以通过app:layout_collapseMode来设置折叠效果

app:layout_collapseMode=”parallax” 视觉差效果,一般配合app:layout_collapseParallaxMultiplier=”0.7”使用,视差系数为0.0~1.0。

app:layout_collapseMode=”pin” 固定模式,Toolbar设置为pin后,可以固定在顶部不被滑出。

判断CollapsingToolbarLayout的状态

可以通过继承AppBarLayout.OnOffsetChangedListener进行监听。

@Override
    public void onOffsetChanged(AppBarLayout mAppBarLayout, int verticalOffset) {
        if (verticalOffset == ) {
                    if (mState != CollapsingToolbarLayoutState.EXPANDED) {
                        mState = CollapsingToolbarLayoutState.EXPANDED;   // 修改状态为展开
                        Log.d("state", "展开");
                    }
                } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                    if (mState != CollapsingToolbarLayoutState.COLLAPSED) {
                        mState = CollapsingToolbarLayoutState.COLLAPSED;   // 修改状态为折叠
                        Log.d("state", "折叠");
                    }
                } else {
                    if (mState != CollapsingToolbarLayoutState.INTERNEDIATE) {
                        mState = CollapsingToolbarLayoutState.INTERNEDIATE;  // 修改状态为中间
                        Log.d("state", "中间");
                    }
                }
    }

    private enum CollapsingToolbarLayoutState {
        EXPANDED, COLLAPSED, INTERNEDIATE
    }
           

五、TabLayout

TabLayout用于配合Viewpager使用,可以很简单的就实现TabPageIndicator的效果。

先看下一些基本属性:

app:tabIndicatorHeight=”@dimen/indicator_height” 指示条高度,想隐藏时可以直接设为0

android:background=”@color/white” TabLayout背景

app:tabIndicatorColor=”@color/black” 指示条颜色

app:tabSelectedTextColor=”@color/black” 选中时的字体颜色

app:tabTextColor=”@color/grey” 正常字体颜色

app:tabMode=”fixed” 模式设置, fixed表示每个tab固定不会动,scrollable表示可以滑动,当有多个时,当前选中tab会一直滑动保持在屏幕正中间,除非不能再滑动。

app:tabMinWidth=”50dp” tab的最小宽度

app:tabGravity=”fill” 可以设置fill或center,fill时tab均分填满,center时,当tab较少时,只挤在中间。

app:tabTextAppearance=”@style/TabLayoutTextStyle” 可以在style中设置字体样式,比如字体大小。

使用的话,有几种方式

1、直接绑定viewpager

mFragmentAdapter = new FragmentAdapter(getSupportFragmentManager());
        mFragmentAdapter.addFragment(new RvListFragment(), "列表");
        mFragmentAdapter.addFragment(new RvGridFragment(), "网格");
        mFragmentAdapter.addFragment(new RvStagFragment(), "瀑布");
        mFragmentAdapter.addFragment(new NestCardFragment(), "卡片");
        viewPager.setAdapter(mFragmentAdapter);
        // 将TabLayout与viewpager绑定
        tabLayout.setupWithViewPager(viewPager);
           

这样子可以直接做出上面图片的效果,简单方便

2、addTab

tabLayout.addTab(tabLayout.newTab().setText("列表"));
tabLayout.addTab(tabLayout.newTab().setText("网格"));
           

或者定义后再添加

private TabLayout.Tab mTabOne;
           

3、参考官方文档, 在布局里添加

<android.support.design.widget.TabLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent">

     <android.support.design.widget.TabItem
             android:text="@string/tab_text"/>

     <android.support.design.widget.TabItem
             android:icon="@drawable/ic_android"/>

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

如果想设置tab图标的话,可以用

如果想设置tab的监听,可以通过AddOnTabSelectedListener(OnTabSelectedListener)。

六、FloatingActionButton

基本属性:

app:backgroundTint=”@color/grey” 背景颜色

* app:rippleColor=”#33728dff”* 点击的背景色

app:elevation=”2dp” 正常阴影大小

app:pressedTranslationZ=”4dp” 按下时的阴影大小

app:fabSize=”normal” 可选的有auto, normal和mini

关于FAB滑动隐藏和弹出子菜单的,可以参考这篇博客以及一个第三方库。

继续阅读