当前位置: 移动技术网 > IT编程>移动开发>Android > 使用CoordinatorLayout打造各种炫酷的效果

使用CoordinatorLayout打造各种炫酷的效果

2019年09月24日  | 移动技术网IT编程  | 我要评论

吉新鹏近况,杭州到上海汽车,清风精品影视论坛

viewpager,scrollview 嵌套viewpager滑动冲突解决

自定义 behavior - 完美仿 qq 浏览器首页,美团商家详情页


coordinatorlayout简介

coordinatorlayout是在 google io/15 大会发布的,遵循material 风格,包含在 support library中,结合appbarlayout, collapsingtoolbarlayout等 可 产生各种炫酷的效果

coordinatorlayout简介通常用来 干什么

google官方地址

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

简单来说就是

  • 作为最上层的view
  • 作为一个 容器与一个或者多个子view进行交互

下面我们一起先来看一下我们实现的效果图

动态图

结合toolbar

结合viewpager

viewpager

结合viewpager的视觉特差


appbarlayout

它是继承与linearlayout的,默认 的 方向 是vertical

类型 说明
int scroll_flag_enter_always when entering (scrolling on screen) the view will scroll on any downwards scroll event, regardless of whether the scrolling view is also scrolling.
int scroll_flag_enter_always_collapsed an additional flag for 'enteralways' which modifies the returning view to only initially scroll back to it's collapsed height.
int scroll_flag_exit_until_collapsed when exiting (scrolling off screen) the view will be scrolled until it is 'collapsed'.
int scroll_flag_scroll the view will be scroll in direct relation to scroll events.
int scroll_flag_snap upon a scroll ending, if the view is only partially visible then it will be snapped and scrolled to it's closest edge.
类型 说明
int scroll_flag_enter_always w((entering) / (scrolling on screen))下拉的时候,这个view也会跟着滑出。
int scroll_flag_enter_always_collapsed 另一种enteralways,但是只显示折叠后的高度。
int scroll_flag_exit_until_collapsed ((exiting) / (scrolling off screen))上拉的时候,这个view会跟着滑动直到折叠。
int scroll_flag_scroll 这个view将会响应scroll事件
int scroll_flag_snap 在scroll滑动事件结束以前 ,如果这个view部分可见,那么这个view会停在最接近当前view的位置

我们可以通过两种 方法设置这个flag

  • 方法一
 setscrollflags(int) 
  • 方法二
 app:layout_scrollflags="scroll|enteralways"

注意事项

appbarlayout必须作为coordinatorlayout的直接子view,否则它的大部分功能将不会生效,如layout_scrollflags等。

首先我们先来看一下我们 效果图一是怎样实现的

代码

<android.support.design.widget.coordinatorlayout
    android:id="@+id/main_content"
    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:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/themeoverlay.appcompat.dark.actionbar">

        <android.support.v7.widget.toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionbarsize"
            android:background="?attr/colorprimary"
            app:layout_scrollflags="scroll|enteralways"
            app:popuptheme="@style/themeoverlay.appcompat.light"/>

       .


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

    <android.support.v7.widget.recyclerview
        android:id="@+id/recyclerview"
        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="end|bottom"
        android:layout_margin="15dp"
        android:src="@drawable/add_2"/>

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

思路 分析

从图中我们可以知道 layout_scrollflags="scroll|enteralways,
前面已经说到layout_scrollflags=scroll的时候,这个view会 跟着 滚动 事件响应,
layout_scrollflags=“enteralways”的时候 这个view会响应下拉事件
所以呈现出来的结果应该是我们在上拉的时候toolbar 会隐藏,下拉的时候toolbar会出来

那如果当我们的toolbar 等于 app:layout_scrollflags="scroll|snap"的时候 ,
layout_scrollflags=scroll的时候,这个view会 跟着 滚动 事件响应,
layout_scrollflags=“snap”的时候 在scroll滑动事件结束以前 ,如果这个view部分可见,那么这个view会停在最接近当前view的位置。
综上呈现的效果如下,代码见toolbarsamplesnar的布局文件

结合viewpager

布局代码如下

<android.support.design.widget.coordinatorlayout
    android:id="@+id/main_content"
    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">


        <imageview android:layout_width="match_parent"
                   android:layout_height="200dp"
                   android:background="?attr/colorprimary"
                   android:scaletype="fitxy"
                   android:src="@drawable/tangyan"
                   app:layout_scrollflags="scroll|enteralways"/>

        <android.support.design.widget.tablayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignparentbottom="true"
            android:background="?attr/colorprimary"
            app:tabindicatorcolor="@color/coloraccent"
            app:tabindicatorheight="4dp"
            app:tabselectedtextcolor="#000"
            app:tabtextcolor="#fff"/>

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


    <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="end|bottom"
        android:layout_margin="15dp"
        android:src="@drawable/add_2"/>

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

思路分析

其实相对于前 一个例子,只是把 摆放recyclerview 的位置替换成viewpager而已,为了有页面导航器的效果,再使用 tablayout而已,而tablayout 在我们滑动的时候最终会停靠在 最顶部,是因为我们没有设置其layout_scrollflags,即tablayout是静态的

运行以后,即可看到以下的结果

viewpager

下面我们一起来看一下 tablayout是怎样结合viewpager直线 导航器的效果的

代码注释 里面已经解释地很清楚了 ,这里我就不解释了

public class viewpagersample extends appcompatactivity {

    viewpager mviewpager;
    list<fragment> mfragments;

    string[] mtitles = new string[]{
            "主页", "微博", "相册"
    };
    private tablayout mtablayout;

    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_third);
        // 第一步,初始化viewpager和tablayout
        mviewpager = (viewpager) findviewbyid(r.id.viewpager);
        mtablayout = (tablayout) findviewbyid(r.id.tabs);
        setupviewpager();
    }

    private void setupviewpager() {

        mfragments = new arraylist<>();
        for (int i = 0; i < mtitles.length; i++) {
            listfragment listfragment = listfragment.newinstance(mtitles[i]);
            mfragments.add(listfragment);
        }
        // 第二步:为viewpager设置适配器
        basefragmentadapter adapter =
                new basefragmentadapter(getsupportfragmentmanager(), mfragments, mtitles);

        mviewpager.setadapter(adapter);
        //  第三步:将viewpager与tablelayout 绑定在一起
        mtablayout.setupwithviewpager(mviewpager);
    }


}

如果我们想更改indicator的相关样式,我们可以在布局文件里面使用

<android.support.design.widget.tablayout
    android:id="@+id/tabs"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignparentbottom="true"
    android:background="?attr/colorprimary"
    app:tabindicatorcolor="@color/coloraccent"
    app:tabindicatorheight="4dp"
    app:tabselectedtextcolor="#000"
    app:tabtextcolor="#fff"/>

如果你不想使用google 帮我们 封装好的控件的话,你也可以自己自定义一个控件,你可以参考我的这一篇博客


在看例子结合viewpager的视觉特差之前 ,我们需要先了解collapsingtoolbarlayout这个控件

collapsingtoolbarlayout

collapsingtoolbarlayout继承与framelayout,官网地址,请自备梯子。

简单来说 ,collapsingtoolbarlayout是工具栏的包装器,它通常作为appbarlayout的孩子。主要实现以下功能

  • collapsing title(可以折叠 的 标题 )
  • content scrim(内容装饰),当我们滑动的位置 到达一定阀值的时候,内容 装饰将会被显示或者隐藏
  • status bar scrim(状态栏布)
  • parallax scrolling children,滑动的时候孩子呈现视觉特差效果
  • pinned position children,固定位置的 孩子

下面我们一起来看一下几个常量

常量 解释说明
int collapse_mode_off the view will act as normal with no collapsing behavior.(这个 view将会 呈现正常的结果,不会表现出折叠效果)
int collapse_mode_parallax the view will scroll in a parallax fashion. see setparallaxmultiplier(float) to change the multiplier used.(在滑动的时候这个view 会呈现 出 视觉特差效果 )
int collapse_mode_pin the view will pin in place until it reaches the bottom of the collapsingtoolbarlayout.(当这个view到达 collapsingtoolbarlayout的底部的时候,这个view 将会被放置,即代替整个collapsingtoolbarlayout)

我们有两种方法可以设置这个常量,

方法一:在代码中使用这个方法

setcollapsemode(int collapsemode)

方法 二:在布局文件中使用自定义属性

app:layout_collapsemode="pin"

到此 ,collapsingtoolbarlayout的一些重要属性已经讲解完毕,下面我们一起来看一下我们是怎样结合viewpager实现视差效果的


结合viewpager的视觉特差

布局代码

<?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:background="@android:color/background_light"
    android:fitssystemwindows="true"
>

    <android.support.design.widget.appbarlayout
        android:id="@+id/main.appbar"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:fitssystemwindows="true"
        android:theme="@style/themeoverlay.appcompat.dark.actionbar"
    >

        <android.support.design.widget.collapsingtoolbarlayout
            android:id="@+id/main.collapsing"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:fitssystemwindows="true"
            app:contentscrim="?attr/colorprimary"
            app:expandedtitlemarginend="64dp"
            app:expandedtitlemarginstart="48dp"
            app:layout_scrollflags="scroll|exituntilcollapsed"
        >

            <imageview
                android:id="@+id/main.backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitssystemwindows="true"
                android:scaletype="centercrop"
                android:src="@drawable/tangyan"
                app:layout_collapsemode="parallax"
            />

            <android.support.v7.widget.toolbar
                android:id="@+id/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.tablayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignparentbottom="true"
            android:background="?attr/colorprimary"
            app:tabindicatorcolor="@color/coloraccent"
            app:tabindicatorheight="4dp"
            app:tabselectedtextcolor="#000"
            app:tabtextcolor="#fff"/>
    </android.support.design.widget.appbarlayout>


    <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.v4.view.viewpager>


    <android.support.design.widget.floatingactionbutton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="15dp"
        android:src="@drawable/add_2"/>

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

效果图如下

思路解析

  • 结构图如图片所示,先说明collapsingtoolbarlayout的变化

    collapsingtoolbarlayout里面 包含imageview 和toolbar,imageview的app:layout_collapsemode="parallax",表示视差效果,toolbar的 app:layout_collapsemode="pin",当这个toobar到达 collapsingtoolbarlayout的底部的时候,会代替整个collapsingtoolbarlayout显示

  • 接着说明tablayout的变化

    从前面的描述我们已经知道当 没有指定app:layout_scrollflags的时候,最终tablayout会静止,不会随着滑动的 时候消失不见

拓展

如果我们仅仅 改变collapsingtoolbarlayout的app:layout_scrollflags="scroll|exituntilcollapsed|snap"的时候,其它代码不变,运行以后,我们将可以看到如下效果图


总结

这篇博客主要讲解了coordinatorlayout,appbarlayout,collapsingtoolbarlayout的一些相关属性。

  • 对于appbarlayout,我们主要 讲解了这个属性app:layout_scrollflags,设置不同 的属性我们可以在滚动的时候显示不同 的效果
  • 对于collapsingtoolbarlayout,我们主要讲解了app:layout_collapsemode这个属性,设置不同的值,我们可以让其子view呈现不同的 炫酷效果,如parallax和pin等

coordinatorlayout的相关用法还有很多,有兴趣 了解的请自行阅读: 官方文档地址


题外话

coordinatorlayout这个控件真的很强大,使用它可以实现各种炫酷的效果,简化了开发者的许多工作,有能力的话可以去研究一下源码 ,看是怎样实现的?

参考文章:

源码下载地址:https://github.com/gdutxiaoxu/coordinatorlayoutexample.git

欢迎大家关注我的微信公众号号 stormjun949(徐公码字),即可关注。 目前专注于 android 开发,主要分享 android开发相关知识和一些相关的优秀文章,包括个人总结,职场经验等。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网