CoordinatorLayout实现工具栏及页面头部的伸缩与折叠

CoordinatorLayout可以实现工具栏及页面头部的伸缩与折叠,这里记录一下其实现的过程与其中注意的事项。最简单的方法就是在建立Activity模板的时候,选择一下叫ScrollingActivity的,它就帮我们实现了一个简单的可折叠的效果。下图就是默认的效果:
这里写图片描述

代码如下:

<?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.example.cg.coordinatorlayoutlearn.ScrollingActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <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/AppTheme.PopupOverlay" />

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

    <include layout="@layout/content_scrolling" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email"
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="bottom|end" />

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

这里面,我们要注意一些地方
1、 CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout组合在一起用才会出现这种效果,不要光拿着CoordinatorLayout来进行处理,这样你是做不出来这个效果的。

2、android:fitsSystemWindows=”true”的作用,fitsSystemWindows官方给的解释是:正常情况,contentview可用的空间是去除了actionbar,title,底部按键的空间后剩余的可用区域;这个属性设置为true,则忽略,false则不忽略。说白了,就是工具栏是否会参与到你的伸缩折叠中来。我的模拟器android版本低,看不出来效果,这个就拿真机看一下效果吧。

3、CoordinatorLayout与AppBarLayout以及要进行伸缩的内部控件,都要添加fitsSystemWindows=”true”的属性。如果不加,会有不一样的效果哦。

4, 伸缩折叠的部分一定要放在CollapsingToolbarLayout内部。这个控件直译过一是折叠的toolbar,它继承自framelayout,所以大家就明白了。它应该有什么的功能了。

5, toolbar如果在CollapsingToolbarLayout内部,那么折叠之后CollapsingToolbarLayout的高度就是toolbar。

6, CollapsingToolbarLayout折叠到最顶端时,它就是老大,会处于最上层,包括toolbar在内,所有的布局都会被他盖住,显示不出来。

下面再说一下,这三个控件中一些我们常用到的属性

一、AppBarLayout的直接子控件可以设置属性:layout_scrollFlags(这里注意啊。是直接子控件),在我们这里是CollapsingToolbarLayout

  1、scroll:将此布局和滚动时间关联。这个标识要设置在其他标识之前,没有这个标识则布局不会滚动且其他标识设置无效。
  
  2、enterAlways:任何向下滚动操作都会使此布局可见。这个标识通常被称为“快速返回”模式。
  
  3、enterAlwaysCollapsed:假设你定义了一个最小高度(minHeight)同时enterAlways也定义了,那么view将在到达这个最小高度的时候开始显示,并且从这个时候开始慢慢展开,当滚动到顶部的时候展开完。

  4、exitUntilCollapsed:当你定义了一个minHeight,此布局将在滚动到达这个最小高度的时候折叠。

  5、snap:当一个滚动事件结束,如果视图是部分可见的,那么它将被滚动到收缩或展开。例如,如果视图只有底部25%显示,它将折叠。相反,如果它的底部75%可见,那么它将完全展开。

二、CollapsingToolbarLayout直接子布局可以使用的属性:app:layout_collapseMode(折叠模式,这里注意,直接子控件),在这个页面中是Toolbar。

  1、off:这个是默认属性,布局将正常显示,没有折叠的行为。

  2、pin:CollapsingToolbarLayout折叠后,此布局将固定在顶部。
   
  3、parallax:CollapsingToolbarLayout折叠时,此布局也会有视差折叠效果。
  
  当CollapsingToolbarLayout的子布局设置了parallax模式时,我们还可以通过app:layout_collapseParallaxMultiplier设置视差滚动因子,值为:0~1。这个值改变之后,你会发现设置此值的控件,不会被固定,值越小,会越往上,我做测试的时候,0.3的时候,控件就会冲出屏幕的上边界。

三、<include layout="@layout/content_scrolling" />就是下方的内容部分,这里面有两点需要注意:

  1、这里面的滚动布局,只能是NestedScrollView与RecyclerView这两个,ScrollView与ListView是不支持的。

  2、必须设置app:layout_behavior=”@string/appbar_scrolling_view_behavior”,才会产生滚动效果。

 OK,到此一个简单的伸缩折叠效果我们就出来了。

下面我们再来做点变化,效果图(csdn只让上传2M)。

这里写图片描述

我们来看一下,变化有哪些

1、toolbar工具栏一直固定在头部,title文字不会随着伸缩而变动。

2、添加了返回按钮,与更多的菜单。

3、滚动到顶部时,title的文字居中,并且变成别的。点击时展开,并且背景图变化。

4、背景图再次滚动顶部,再下拉时,背景图恢复到原来的图。

我们来一步一步完成上面的四个变化

一、toolbar工具栏一直固定在头部,title文字不会随着伸缩而变动  

 1、toolbar的属性app:layout_collapseMode设置成pin。它就会一直固定在头部了。

 2、CollapsingToolbarLayout控件添加app:titleEnabled="false"属性或是在后台设置setTitleEnabled = false;就会让文字不会随着伸缩而变来变去了。

二,添加了返回按钮,与更多的菜单

 1、添加返回按钮,只需要在后台代码 oncreate中添加`getSupportActionBar().setDisplayHomeAsUpEnabled(true);`就行了,点击事件是
  @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          if (item.getItemId() == android.R.id.home) {
              onBackPressed();
              return true;
          }
          return super.onOptionsItemSelected(item);
      }
 2、更多菜单,就相当简单了,与我们平时用toolbar是一样的
     @Override
      public boolean onCreateOptionsMenu(Menu menu)
      {
          getMenuInflater().inflate(R.menu.menu_main, menu);
          return true;
      }

三、滚动到顶部时,title的文字居中,并且变成别的。点击时展开,并且背景图变化

  1、我们要先设置一个背景图,把原来兰色背景换成一个图,这里要说明,你这个图的大小要一些。不然滑动会卡。我们在CollapsingToolbarLayout内部,添加一个ImageView控件,做为它的子控件,这个子控件要放在Toolbar之前
   

       <ImageView
                android:id="@+id/img_Head"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:src="@drawable/scenery1"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"
                android:fitsSystemWindows="true"/>

   运行一下,你会发现,背景变成了我们换上去的图。

2、我们要让title的文字居中,并且改变文字,这个就是要在Toolbar中,添加一个控件ButtonBarLayout,代码如下:
<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/AppTheme.PopupOverlay">


                <android.support.v7.widget.ButtonBarLayout
                    android:id="@+id/btn_Play"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:gravity="center"
                    android:visibility="gone">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textColor="#ffffff"
                        android:text="洗脑大全"
                        android:layout_gravity="center_vertical"
                        />
                </android.support.v7.widget.ButtonBarLayout>
            </android.support.v7.widget.Toolbar>

    注意,这里我们是把ButtonBarlayout隐藏的,如果你不隐藏,你会发现,它会把我们正常设置的title文字直接就覆盖掉了。所以初始的时候我们就会隐掉它。当滚动到顶部的时候再显示它。我们通过什么方式来取得滚动到哪里了呢,CollapsingToolbarLayout没有提供相应的方法,这样,我们只能去找AppBarLayout了,它有一个关于它的偏移量改变的事件。我们通过它来处理:
    1) 定义一下状态

    private CollapsingToolbarLayoutState state;

    private enum CollapsingToolbarLayoutState {
        EXPANDED,
        COLLAPSED,
        INTERNEDIATE
    }
state = CollapsingToolbarLayoutState.EXPANDED;

        Appbar_main.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

                if(verticalOffset==0)
                {
                    //全展开
                    if (state != CollapsingToolbarLayoutState.EXPANDED) {
                        state = CollapsingToolbarLayoutState.EXPANDED;//修改状态标记为展开
                        //Ctl_toolbar.setTitle("心灵鸡汤");//设置title为EXPANDED
                    }
                }else if(Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange())
                {
                    if (state != CollapsingToolbarLayoutState.COLLAPSED) {

                        //Ctl_toolbar.setTitle("34567");//设置title不显示
                        btn_Play.setVisibility(View.VISIBLE);//隐藏播放按钮
                        state = CollapsingToolbarLayoutState.COLLAPSED;//修改状态标记为折叠

                        if(img_two.getVisibility()==View.VISIBLE) {
                            img_Head.setVisibility(View.VISIBLE);
                            img_two.setVisibility(View.GONE);
                        }
                    }
                }else{
                    if (state != CollapsingToolbarLayoutState.INTERNEDIATE) {
                        if(state == CollapsingToolbarLayoutState.COLLAPSED){
                            btn_Play.setVisibility(View.GONE);//由折叠变为中间状态时隐藏播放按钮
                        }
                        //Ctl_toolbar.setTitle("洗脑大全");//设置title为INTERNEDIATE
                        state = CollapsingToolbarLayoutState.INTERNEDIATE;//修改状态标记为中间
                    }
                }
            }
        });

  3、点击时图片改动,这个比较简单了,就是隐藏一个图,显示一个图,我们再加一个ImageView

    <!--封面图片-->
            <ImageView
                android:id="@+id/img_Head"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:src="@drawable/scenery1"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"
                android:fitsSystemWindows="true"/>

            <ImageView
                android:id="@+id/img_two"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:src="@drawable/p2"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"
                android:fitsSystemWindows="true"
                android:visibility="gone"/>
  这回就明白了吧。

四、背景图再次滚动顶部,再下拉时,背景图恢复到原来的图
   
   这个我在偏移量的代码中已经给出了。就是
   

else if(Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange())
                {
                    if (state != CollapsingToolbarLayoutState.COLLAPSED) {

                        //Ctl_toolbar.setTitle("34567");//设置title不显示
                        btn_Play.setVisibility(View.VISIBLE);//隐藏播放按钮
                        state = CollapsingToolbarLayoutState.COLLAPSED;//修改状态标记为折叠

                        if(img_two.getVisibility()==View.VISIBLE) {
                            img_Head.setVisibility(View.VISIBLE);
                            img_two.setVisibility(View.GONE);
                        }
                    }

我是参与了,下面的这些blog来记录这些的,感谢这些兄弟的分享。
http://www.jianshu.com/p/06c0ae8d9a96
http://blog.csdn.net/qq_31340657/article/details/51918773
http://blog.csdn.net/u012702547/article/details/51286288

下载地址: http://download.csdn.net/detail/chenguang79/9755615

发布了305 篇原创文章 · 获赞 261 · 访问量 184万+

猜你喜欢

转载自blog.csdn.net/chenguang79/article/details/55255220