实现折叠工具栏CollapsingToolbarLayout(折叠工具栏布局)

1、相关知识点介绍

AppBarLayout简介:
该控件是Design包下的一个控件,AppBarLayout就是用来装AppBar的容器,是LinearLayout的子类。而AppBar就包含咱们一般所知道的ActionBar,Toolbar。
AppBarLayout要点:
功能:让子View(AppBar)能够选择他们本身的滚动行为。
注意:须要依赖CoordinatorLayout做为父容器,同时也要求一个具备能够独立滚动的兄弟节点(或兄弟节点的子view能够滚动[即RecycleView、NestedScrollView])才能发挥其功能。

CoordinatorLayout简介:
该控件是Design包下的一个控件,是组织它众多子view之间互相协做的一个ViewGroup。CoordinatorLayout 的神奇之处就在于 Behavior 对象。CoordinatorLayout使用 Behavior 对象进行通讯,使得其子view之间知道了彼此的存在,一个子view的变化能够通知到另外一个子view。CoordinatorLayout 所作的事情就是当成一个通讯的桥梁,链接不一样的view。并且 design库的动态效果都依赖于该控件。

coordinatorLayout常见的用法就是:给它的一个子元素A设置一个layout_scrollFlags的属性,而后给另一个子元素B设置一个layout_behavior=”@string/appbar_scrolling_view_behavior”的属性,这个子元素B通常是一个能够滑动的控件,好比RecyclerView、NestedScrollView等,那么当子元素B滑动的时候,子元素A就会根据其layout_scrollFlags的属性值而作出不一样的改变,因此咱们要为CollapsingToolbarLayout设置layout_scrollFlags属性。

CollapsingToolbarLayout介绍:
        collapsingToolbarLayout通常不会单独出如今布局文件中,而是做为另外一个控件CoordinatorLayout的子元素出现,CoordinatorLayout(协调布局)这个控件很强大, design库的动态效果都依赖于该控件。
经常使用属性
app:contentScrim:当Toolbar收缩到必定程度时的所展示的主体颜色。即Toolbar的颜色。
app:title:当titleEnable设置为true的时候,在toolbar展开的时候,显示大标题,toolbar收缩时,显示为toolbar上面的小标题。 
app:scrimAnimationDuration:该属性控制toolbar收缩时,颜色变化的动画持续时间。即颜色变为contentScrim所指定的颜色进行的动画所须要的时间 
app:collapsedTitleTextAppearance:指定toolbar收缩时,标题字体的样式。
app:collapsedTitleGravity : 指定toolbar收缩时的标题文字对齐方式。
app:expandedTitleTextAppearance : 指定toolbar展开后的标题文字字体。
app:expandedTitleGravity:指定toolbar展开时,title所在的位置。相似的还有expandedTitleMargin、collapsedTitleGravity这些属性。
app:expandedTitleMargin : 指定展开后的标题四周间距。
app:expandedTitleMarginStart/app:expandedTitleMarginTop/app:expandedTitleMarginEnd/app:expandedTitleMarginBottom : 指定展开后的标题具体方向的间距。

CarView简介:
CardView继承FrameLayout,因此CardView是一个ViewGroup,咱们能够在里面添加一些控件进行布局。
特殊点就是有rounded corner(圆角)和shadow(阴影),这个就是它的特殊之处,回首往日,咱们须要自定义shape文件进行实现圆角和阴影的设计,如今google的大牛已经把它设计为CardView的属性供咱们设置进行使用。
CarView经常使用属性:
app:contentPadding:内容的padding
app:cardBackgroundColor 设置背景色
app:cardElevation 设置z轴阴影
app:cardMaxElevation 设置z轴最大高度值
app:cardUseCompatPadding 是否使用CompadPadding
app:cardPreventCornerOverlap 是否使用PreventCornerOverlap
app:contentPaddingLeft 内容的左padding
app:contentPaddingTop 内容的上padding
app:contentPaddingRight 内容的右padding
app:contentPaddingBottom 内容的底padding

2、实现效果

    

3、实现步骤
一、项目结构

二、准备工做
1).添加依赖
       使用这些控件时,须要引入Android Design Library这个库,同时地,咱们须要把app的主题也要作相应的修改以便适应这个控件,因此咱们也须要appcompat这个库,引入cardview库,那么咱们在build.gradle文件中引入以下:


compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
    compile 'com.android.support:design:26.0.0-alpha1'
    compile 'com.android.support:cardview-v7:26.0.0-alpha1'

2).修改style.xml文件,用AppCompat兼容库中的主题,且设置成NoActionBar(没有活动栏)
注意事项:
item的name是colorPrimary而不是android:colorPrimary

html

<resources>
  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#269fe2</item>
        <item name="colorPrimaryDark">#3A5FCD</item>
    </style>
</resources>

3).字符串资源文件string.xml

<resources>
    <string name="app_name">折叠工具栏</string>
    <string name="content">Learn and Share Android,Learn and Share Android,Learn and Share Android,Learn and Share Android,Learn and Share Android</string>
</resources>

4.将图片资源方法mipmap文件夹中

5.修改activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="200dp">
       <!-- app:contentScrim 设置当工具栏收缩必定程度时所展现的主体颜色,-->
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:minHeight="200dp"
            app:collapsedTitleGravity="left"
            app:expandedTitleMarginStart="10dp"
            app:expandedTitleMarginEnd="10dp"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <!--ImageView应当方Toolbar上面,由于CollapsingToolbarLayout是帧式布  局,如方下面就在最上层,会被覆盖-->
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@mipmap/ic_bg"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.3"/>
 <!--这里工具栏颜色默认是透明,当工具栏折叠后CollapsingToolbarLayout的颜色充当Toolbar背景颜色-->
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin">
            </android.support.v7.widget.Toolbar>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingTop="24dp">
            <include layout="@layout/item_card"/>
            <include layout="@layout/item_card"/>
            <include layout="@layout/item_card"/>
            <include layout="@layout/item_card"/>
            <include layout="@layout/item_card"/>
            <include layout="@layout/item_card"/>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
6.在layout文件夹中建立item_card.xml文件
 
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 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="wrap_content"
    android:layout_margin="10dp"
    app:contentPadding="10dp"
    app:cardElevation="10dp"
    app:cardCornerRadius="10dp">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Card"
        android:textSize="20sp" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/content"/>
</android.support.v7.widget.CardView>
7.修改MainActivity.java文件内容
注意此处MainActivity继承的是AppCompatActivity而不是Activity
 
 
public class MainActivity extends AppCompatActivity {
    Toolbar toolbar;
    CollapsingToolbarLayout mCollapsingToolbarLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
        mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.WHITE);
        mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);
    }
}
4、总结
常见错误:
错误一:效果以下

致使错误缘由:
控件ImageView应该放在布局CollapsingToolbarLayout下的,而不是放在控件ToolBar。
错误二:效果以下

致使错误缘由:
没有给能够滚动的视图(即NestedScrollView)设置布局行为(即app:layout_behavior)。
app:layout_behavior="@string/appbar_scrolling_view_behavior"

错误三:工具栏折叠后不变颜色
效果以下

致使错误缘由:
缘由1:控件Toolbar应该放在控件ImageView的下方。因为布局 CollapsingToolbarLayout继承的是FrameLayout(帧式布局),因此它也是帧式布局,控件ImageView宽和高设置的是充分父控件(CollapsingToolbarLayout),若是控件Toolbar位置放在了控件ImageView的上方(与就是Toolbar在底层,而ImageView在它上面一层),则Toolbar会被ImageView彻底覆盖,因此致使看不见。

缘由2:须要给布局CollapsingToolbarLayout设置属性 app:contentScrim="颜色"(我这里设置的是" ?attr/colorPrimary " 即系统中工具栏的颜色,也能够设置其余值如"#f00" ),app:contentScrim属性做用是设置当工具栏收缩必定程度时所展现的主体颜色;

错误四:
(工具栏不折叠)效果以下
致使错误缘由:
没有给CollapsingToolbarLayout(折叠工具栏布局)设置滚动标志app:layout_scrollFlags。
应该设置app:layout_scrollFlags="scroll",才能滚动。

小结:在coordinatorLayout作父布局的状况下,给滑动控件设置一个app:layout_behavior="@string/appbar_scrolling_view_behavior"标志位,当带有该标志位的控件滑动时会触发带有layout_scrollFlags标志位的另外一个控件滑动。此时imageview的layout_collapseMode是parallax,因此它会以有视差的方式来相对滑动,而toolbar设置了pin的标记位,因此在收缩后会固定在屏幕顶部。