整理自:
http://www.itdecent.cn/p/d159f0176576
實(shí)現(xiàn)如下效果:
代碼如下:
<?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.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/main.backdrop"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:scaleType="centerCrop"
android:src="@drawable/material_img"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="50dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/my_txt"
android:textSize="20sp" />
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
主要涉及以下幾個(gè)控件:
我們把整個(gè)布局分為2個(gè)部分,一個(gè)是頂部的toolbar(包括里面的imageView和textView),一個(gè)是底部的可滑動(dòng)的文字區(qū)域
一、CoordinatorLayout(協(xié)調(diào)者布局):
這個(gè)主要是協(xié)調(diào)dependency(頂部的toolbar區(qū)域)和child(可滾動(dòng)的文字區(qū)域,有app:layout_behavior這個(gè)屬性,所以是child,根據(jù)dependency做出自己的變化)之間的關(guān)系,但是注意dependency和child之間的變換關(guān)系到底是怎么樣的,CoordinatorLayout這個(gè)布局是不關(guān)心也無法設(shè)置的,所有的設(shè)置都在child的app:layout_behavior中設(shè)置,我們?nèi)绻约簯械萌ダ^承CoordinatorLayout.Behavior<T>去自己寫這個(gè)變換的邏輯
(參考博客:http://www.itdecent.cn/p/72d45d1f7d55#)
谷歌已經(jīng)幫我們寫好了一個(gè)現(xiàn)成的Behavior去實(shí)現(xiàn)我們上述想要的效果,即
NestedScrollView:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!--將你的內(nèi)容放在這里-->
</android.support.v4.widget.NestedScrollView>
把textView控件放入其中,就可以實(shí)現(xiàn)child和dependency之間聯(lián)動(dòng)的效果。
二、CollapsingToolbarLayout(收縮的toolbar布局):
**:注意CollapsingToolbarLayout是繼承于FrameLayout的,所以里面元素的擺放要注意先后順序,否則一些視覺元素會被遮擋!
**:所有你預(yù)期效果中要收縮不見的部分都要放在這個(gè)布局里面!
**:為這個(gè)布局本身設(shè)置屬性:
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
**:最后的snap屬性是新加的:解釋如下
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/1019/3594.html
假設(shè)里面有3個(gè)元素:
一個(gè)imageView,設(shè)置其app:layout_collapseMode="···"
none
parallax
pin 2者區(qū)別就是parallax在整個(gè)布局上劃的時(shí)候會有向上微微的移動(dòng),有一種奇妙的視覺效果,而pin則是在整個(gè)布局上劃的時(shí)候不會有變化,直到布局還要向上移動(dòng)超過了圖片的界限,圖片就會快速地向上消失 ,而none則是圖片會在整個(gè)布局上劃的一開始就會做出快速地向上消失的效果
**在AppBarLayout中, 添加CollapsingToolbarLayout控件, CollapsingToolbar會滾動(dòng)消失, 被ToolBar替換, 實(shí)現(xiàn)滾動(dòng)動(dòng)畫
可以實(shí)現(xiàn)收縮的toolbar效果,里面需要有toolbar控件和其他你需要的控件,可以設(shè)置的屬性:
CollapsingToolbarLayout 提供以下屬性和方法是用:
- Collapsing title:ToolBar的標(biāo)題,當(dāng)CollapsingToolbarLayout全屏沒有折疊時(shí),title顯示的是大字體,在折疊的過程中,title不斷變小到一定大小的效果。你可以調(diào)用setTitle(CharSequence)方法設(shè)置title。
- Content scrim:ToolBar被折疊到頂部固定時(shí)候的背景,你可以調(diào)用setContentScrim(Drawable)方法改變背景或者 在屬性中使用 app:contentScrim=”?attr/colorPrimary”來改變背景。
- Status bar scrim:狀態(tài)欄的背景,調(diào)用方法setStatusBarScrim(Drawable)。還沒研究明白,不過這個(gè)只能在Android5.0以上系統(tǒng)有效果。
- Parallax scrolling children:CollapsingToolbarLayout滑動(dòng)時(shí),子視圖的視覺差,可以通過屬性app:layout_collapseParallaxMultiplier=”0.6”改變。值de的范圍[0.0,1.0],值越大視察越大。
- CollapseMode :子視圖的折疊模式,在子視圖設(shè)置,有兩種“pin”:固定模式,在折疊的時(shí)候最后固定在頂端;“parallax”:視差模式,在折疊的時(shí)候會有個(gè)視差折疊的效果。我們可以在布局中使用屬性app:layout_collapseMode=”parallax”來改變。
CoordinatorLayout 還提供了一個(gè) layout_anchor 的屬性,連同 layout_anchorGravity 一起,可以用來放置與其他視圖關(guān)聯(lián)在一起的懸浮視圖(如 FloatingActionButton)。
通過下面的參數(shù)設(shè)置了FloatingActionButton的位置,兩個(gè)屬性共同作用使得FAB 浮動(dòng)按鈕也能折疊消失,展現(xiàn)。
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
(全部代碼見:http://blog.csdn.net/xyz_lmn/article/details/48055919)
三、AppBarLayout(AppBar布局):
我們必須使用AppBarLayout來讓Toolbar響應(yīng)滾動(dòng)事件。
定制當(dāng)某個(gè)可滾動(dòng)View的滾動(dòng)手勢發(fā)生變化時(shí),其內(nèi)部的子View實(shí)現(xiàn)何種動(dòng)作。
注意這里的“某個(gè)可滾動(dòng)View”是外部的,即這里的文本區(qū)域(我們給textView加了NestedScrollView,所以也是一個(gè)可滾動(dòng)View),
“內(nèi)部的子View”就是用CollapsingToolbarLayout包起來的帶圖片的toolbar區(qū)域了,注意“內(nèi)部的子View實(shí)現(xiàn)何種動(dòng)作”是在子View屬性app:layout_scrollFlags設(shè)置相關(guān)的值:
那么app:layout_scrollFlags可以設(shè)置哪些動(dòng)作呢?分別如下:
(1) scroll:值設(shè)為scroll的View會跟隨滾動(dòng)事件一起發(fā)生移動(dòng)。
什么意思呢?簡單的說,就是當(dāng)指定的ScrollView發(fā)生滾動(dòng)時(shí),該View也跟隨一起滾動(dòng),就好像這個(gè)View也是屬于這個(gè)ScrollView一樣。
一張gif足以說明:
對應(yīng)的布局文件
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll" />
</android.support.design.widget.AppBarLayout>
(2) enterAlways:值設(shè)為enterAlways的View,當(dāng)ScrollView往下滾動(dòng)時(shí),該View會直接往下滾動(dòng)。而不用考慮ScrollView是否在滾動(dòng)。
看個(gè)動(dòng)畫片(Y(o)Y)
ToolBar高度設(shè)為:
android:attr/actionBarSize,app:layout_scrollFlags="scroll|enterAlways"
(3) exitUntilCollapsed:值設(shè)為exitUntilCollapsed的View,當(dāng)這個(gè)View要往上逐漸“消逝”時(shí),會一直往上滑動(dòng),直到剩下的的高度達(dá)到它的最小高度后,再響應(yīng)ScrollView的內(nèi)部滑動(dòng)事件。
怎么理解呢?簡單解釋:在ScrollView往上滑動(dòng)時(shí),首先是View把滑動(dòng)事件“奪走”,由View去執(zhí)行滑動(dòng),直到滑動(dòng)最小高度后,把這個(gè)滑動(dòng)事件“還”回去,讓ScrollView內(nèi)部去上滑??磦€(gè)gif感受一下
圖中將高度設(shè)的比較大:200dp,并將最小高度設(shè)置為?android:attr/actionBarSize,app:layout_scrollFlags="scroll|exitUntilCollapsed"):
(4) enterAlwaysCollapsed:是enterAlways的附加選項(xiàng),一般跟enterAlways一起使用,它是指,View在往下“出現(xiàn)”的時(shí)候,首先是enterAlways效果,當(dāng)View的高度達(dá)到最小高度時(shí),View就暫時(shí)不去往下滾動(dòng),直到ScrollView滑動(dòng)到頂部不再滑動(dòng)時(shí),View再繼續(xù)往下滑動(dòng),直到滑到View的頂部結(jié)束。
來個(gè)gif感受一下(圖中將高度設(shè)的比較大:200dp,并將最小高度設(shè)置為?android:attr/actionBarSize,app:layout_scrollFlags="scroll|enerAlways|enterAlwaysCollapsed"):