Android折疊式Toolbar使用完全解析(CollapsingToolbarLayout)
簡(jiǎn)介
在各種不同的應(yīng)用中,大家可能會(huì)經(jīng)常見(jiàn)到這樣一個(gè)效果:Toolbar是透明的,有著一個(gè)背景圖片以及大標(biāo)題,隨著頁(yè)面向上滑動(dòng),其標(biāo)題逐漸縮放到Toolbar上,而背景圖片則在滑動(dòng)到一定程度后變成了Toolbar的顏色,這種效果也即是折疊式效果。其實(shí)這種效果在GitHub上面已經(jīng)有很多開(kāi)源庫(kù)實(shí)現(xiàn)了,但是Google在其推出的Design Library庫(kù)中也給出了一個(gè)這種控件,讓我們很方便地實(shí)現(xiàn)了這種效果。這個(gè)控件是CollapsingToolbarLayout,它是一個(gè)增強(qiáng)型的FrameLayout。那么,本篇文章就給大家詳細(xì)地介紹該控件的使用方法以及注意事項(xiàng)。
效果
本文結(jié)合一個(gè)Demo來(lái)進(jìn)行演示,下面是最終的顯示效果,也即折疊式Toolbar的效果:
引入
使用該控件,需要引入Android Design Library這個(gè)庫(kù),同時(shí)地,我們需要把a(bǔ)pp的主題也要做相應(yīng)的修改以便適應(yīng)這個(gè)控件,所以我們也需要appcompat這個(gè)庫(kù),那么我們?cè)赽uild.gradle文件中引入如下:
dependencies { compile 'com.android.support:cardview-v7:24.1.0' //cardview compile 'com.android.support:design:24.1.0' compile 'com.android.support:appcompat-v7:24.1.0' }
本文內(nèi)容均基于官方文檔,有興趣的讀者可以前往官方文檔進(jìn)一步查看(自備梯子)。
知識(shí)儲(chǔ)備
接下來(lái),筆者一步步地介紹該控件的用法。首先,我們先來(lái)了解這個(gè)控件的常用xml屬性。
一、常用xml屬性介紹
1)contentScrim:當(dāng)Toolbar收縮到一定程度時(shí)的所展現(xiàn)的主體顏色。即Toolbar的顏色。
2)title:當(dāng)titleEnable設(shè)置為true的時(shí)候,在toolbar展開(kāi)的時(shí)候,顯示大標(biāo)題,toolbar收縮時(shí),顯示為toolbar上面的小標(biāo)題。
3)scrimAnimationDuration:該屬性控制toolbar收縮時(shí),顏色變化的動(dòng)畫(huà)持續(xù)時(shí)間。即顏色變?yōu)閏ontentScrim所指定的顏色進(jìn)行的動(dòng)畫(huà)所需要的時(shí)間。
4)expandedTitleGravity:指定toolbar展開(kāi)時(shí),title所在的位置。類(lèi)似的還有expandedTitleMargin、collapsedTitleGravity這些屬性。
5)collapsedTitleTextAppearance:指定toolbar收縮時(shí),標(biāo)題字體的樣式,類(lèi)似的還有expandedTitleTextAppearance。
二、常見(jiàn)的標(biāo)志位
一般開(kāi)發(fā)中,CollapsingToolbarLayout不會(huì)單獨(dú)出現(xiàn)在布局文件中,而是作為另一個(gè)控件CoordinatorLayout的子元素出現(xiàn),那么CoordinatorLayout又是什么呢?其實(shí)CoordinatorLayout這個(gè)控件很強(qiáng)大,能對(duì)其子元素實(shí)現(xiàn)多種不同的功能,一個(gè)常見(jiàn)的用法就是:給它的一個(gè)子元素A設(shè)置一個(gè)layout_scrollFlags的屬性,然后給另外一個(gè)子元素B設(shè)置一個(gè)layout_behavior=”@string/appbar_scrolling_view_behavior”的屬性,這個(gè)子元素B一般是一個(gè)可以滑動(dòng)的控件,比如RecyclerView、NestedScrollView等,那么當(dāng)子元素B滑動(dòng)的時(shí)候,子元素A就會(huì)根據(jù)其layout_scrollFlags的屬性值而做出不同的改變,所以我們要為CollapsingToolbarLayout設(shè)置layout_scrollFlags屬性。
layout_scrollFlags
我們來(lái)看看layout_scrollFlags有哪幾個(gè)屬性可以選擇:
* scroll:所有想要滑動(dòng)的控件都要設(shè)置這個(gè)標(biāo)志位。如果不設(shè)置這個(gè)標(biāo)志位,那么View會(huì)固定不動(dòng)。
* enterAlways:設(shè)置了該標(biāo)志位后,若View已經(jīng)滑出屏幕,此時(shí)手指向下滑,View會(huì)立刻出現(xiàn),這是另一種使用場(chǎng)景。
* enterAlwaysCollapsed:設(shè)置了minHeight,同時(shí)設(shè)置了該標(biāo)志位的話,view會(huì)以最小高度進(jìn)度屏幕,當(dāng)滑動(dòng)控件滑動(dòng)到頂部的時(shí)候才會(huì)拓展為完整的高度。
* exitUntilCollapsed:向上滑動(dòng)時(shí)收縮當(dāng)前View。但view可以被固定在頂部。
可能直接用語(yǔ)言來(lái)描述還是有點(diǎn)太抽象,下面會(huì)以實(shí)際的效果給大家展示這幾個(gè)標(biāo)志位的具體作用。
layout_collapseMode
上面提到CollapsingToolbarLayout是一個(gè)FrameLayout,它內(nèi)部能有多個(gè)子元素,而子元素也會(huì)有不同的表現(xiàn)。比如說(shuō),在上面的GIF圖中,toolbar在縮放后是固定在頂部的,而imageview則是隨著布局的滾動(dòng)而滾動(dòng),也即存在一個(gè)相對(duì)滾動(dòng)的過(guò)程。所以這些子元素可以添加layout_collapseMode標(biāo)志位進(jìn)而產(chǎn)生不同的行為。其實(shí)這里也只有兩種標(biāo)志位,分別是:
* pin:有該標(biāo)志位的View在頁(yè)面滾動(dòng)的過(guò)程中會(huì)一直停留在頂部,比如Toolbar可以被固定在頂部
* parallax:有該標(biāo)志位的View表示能和頁(yè)面同時(shí)滾動(dòng)。與該標(biāo)志位相關(guān)聯(lián)的一個(gè)屬性是:layout_collapseParallaxMultiplier,該屬性是視差因子,表示該View與頁(yè)面的滾動(dòng)速度存在差值,造成一種相對(duì)滾動(dòng)的效果。
三、常用的層級(jí)關(guān)系
上面說(shuō)到CollapsingToolbarLayout一般作為CoordinatorLayout的子元素出現(xiàn),其實(shí)如果要實(shí)現(xiàn)上面的效果,還需要另外一個(gè)控件:AppBarLayout。該控件也是Design庫(kù)的控件,作用是把其所有子元素當(dāng)做一個(gè)AppBar來(lái)使用。一般來(lái)說(shuō),實(shí)現(xiàn)折疊式Toolbar可以使用以下的層級(jí)關(guān)系:
<android.support.design.widget.CoordinatorLayout...> <android.support.design.widget.AppBarLayout...> <android.support.design.widget.CollapsingToolbarLayout...> <!-- your collapsed view --> <View.../> <android.support.v7.widget.Toolbar.../> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <!-- Scroll view --> <android.support.v7.widget.RecyclerView.../> </android.support.design.widget.CoordinatorLayout>
從上面的層級(jí)關(guān)系來(lái)看,最外面的一層是CoordinatorLayout,它有兩個(gè)子元素,分別是AppBarLayout和RecyclerView(可滑動(dòng)控件),而AppBarLayout則包裹著CollapsingToolbarLayout,CollapsingToolbarLayout的子元素分別是被折疊的View(可以是一張圖片,也可以是一個(gè)布局)以及我們的Toolbar。
例子①
有了以上的知識(shí)儲(chǔ)備,我們就可以開(kāi)始動(dòng)手寫(xiě)代碼了,我們的目標(biāo)是實(shí)現(xiàn)上面的gif圖的效果。
1、在activity_main.xml文件中(注:以下注釋只是為了方便說(shuō)明):
<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="200dp" android:fitsSystemWindows="true"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="?attr/colorPrimary" <!--toolbar折疊后的主體顏色 --> app:expandedTitleMarginEnd="10dp" <!--文字展開(kāi)時(shí)的Margin --> app:expandedTitleMarginStart="10dp" app:collapsedTitleTextAppearance="@style/TextAppearance.AppCompat.Title" <!--字體的表現(xiàn) --> app:layout_scrollFlags="scroll|exitUntilCollapsed"> <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" app:layout_collapseMode="parallax" <!--設(shè)置imageView可隨著滑動(dòng)控件的滑動(dòng)而滑動(dòng) --> app:layout_collapseParallaxMultiplier="0.5"/> <!--視差因子 --> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" /> <!--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"> <!--為滑動(dòng)控件設(shè)置Behavior,這樣上面的控件才能做出相應(yīng)改變 --> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <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"/> <include layout="@layout/item_card"/> <include layout="@layout/item_card"/> </LinearLayout> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>
與其相關(guān)聯(lián)的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="100dp" android:layout_margin="5dp" app:cardElevation="5dp" app:contentPaddingTop="2dp" app:contentPaddingBottom="2dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Learn and Share Android" android:textSize="20sp" android:layout_gravity="center"/> </android.support.v7.widget.CardView>
2、在MainActivity.java文件中再做出一些處理:
private ImageView iv; private CollapsingToolbarLayout collapsingToolbarLayout; private Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout); iv = (ImageView) findViewById(R.id.iv); toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); toolbar.setNavigationIcon(R.mipmap.ic_drawer_home); collapsingToolbarLayout.setTitle("DesignLibrarySample"); collapsingToolbarLayout.setCollapsedTitleTextColor(Color.WHITE); collapsingToolbarLayout.setExpandedTitleColor(Color.WHITE); iv.setImageResource(R.mipmap.ic_bg); }
上面,我們?yōu)閏ollapsingToolbarLayout設(shè)置了標(biāo)題,以及收縮時(shí)標(biāo)題的顏色和展開(kāi)時(shí)標(biāo)題的顏色等。經(jīng)過(guò)上面的一個(gè)簡(jiǎn)單例子,就能實(shí)現(xiàn)上面gif圖所顯示的折疊式Toolbar的效果了。
這里先小結(jié)一下:在CoordinatorLayout作為父布局的情況下,給滑動(dòng)控件設(shè)置一個(gè)layout_behavior=”@string/appbar_scrolling_view_behavior”標(biāo)志位(該Behavior系統(tǒng)以及幫我們實(shí)現(xiàn)),那么當(dāng)帶有這個(gè)標(biāo)志位的控件滑動(dòng)的時(shí)候會(huì)觸發(fā)帶有scroll_flags標(biāo)志位的另一個(gè)控件進(jìn)行滑動(dòng),此時(shí)imageview的layout_collapseMode是parallax,所以它會(huì)以有視差的方式來(lái)相對(duì)滑動(dòng),而toolbar設(shè)置了pin的標(biāo)記位,所以在收縮后會(huì)固定在屏幕頂部。
例子②
在例子①內(nèi),我們?yōu)镃ollapsingToolbarLayout設(shè)置的scroll_flags是”scroll | exitUntilCollapsed”,那么我們把標(biāo)志位換成別的會(huì)有什么不同的效果呢?
在activity_main.xml內(nèi),作如下修改:
<android.support.design.widget.CollapsingToolbarLayout ... app:layout_scrollFlags="scroll|enterAlwaysCollapsed|enterAlways">
然后別的不作改動(dòng),效果如下:
顯然,所造成的效果發(fā)生了變化,這里toolbar并不一致固定在頂部了,而是隨著滑動(dòng)而滑出了屏幕之外,同時(shí)如果手指向下滑動(dòng),toolbar會(huì)逐漸出現(xiàn)并保持著最小的高度,等到回到了最頂部后,toolbar會(huì)展開(kāi)成原來(lái)的樣子。
那么,基于以上的例子,如果上面少了一個(gè)“enterAlwaysCollapsed”這個(gè)標(biāo)志位又會(huì)怎樣呢?該標(biāo)志位的作用上面也已經(jīng)解釋過(guò)了,是控制toolbar以最小的高度進(jìn)入屏幕,并且在滑動(dòng)控件滑動(dòng)到最頂端的時(shí)候再展開(kāi)成完整的高度。如果少了這個(gè)標(biāo)志位,在我們手指向下滑的時(shí)候,toolbar也會(huì)逐漸出現(xiàn),但是與上面gif圖不同的是,toolbar會(huì)繼續(xù)展開(kāi)變成原來(lái)的樣子,即出現(xiàn)imageview。圖這里就不放出來(lái)了,讀者可以自行驗(yàn)證~
通過(guò)以上的兩個(gè)小例子,我們對(duì)CollapsingToolbarLayout有了一定的認(rèn)識(shí),也學(xué)會(huì)了它的使用方法了,使用它能讓我們的應(yīng)用變得更加美觀。那么最后,我們?cè)賮?lái)談?wù)勛⒁馐马?xiàng),也即筆者開(kāi)發(fā)過(guò)程中遇到的坑。
注意事項(xiàng)
1、Android Design Support Library的使用需要配合特定的主題,一般用AppCompat下的主題即可,也可以自定義主題,繼承自AppCompat的主題,否則會(huì)報(bào)錯(cuò)。另外如果使用Android Studio的話,主題的相關(guān)代碼需要在styles.xml(v21)文件內(nèi)做出相應(yīng)的修改,否則使用Android 5.0以上的機(jī)子做測(cè)試的話也會(huì)報(bào)錯(cuò)。
2、由于使用了AppCompat的主題,那么我們的Activity應(yīng)該繼承自AppCompatActivity。
3、筆者之前使用design support library的版本號(hào)是23.1.0,在此版本上,CollapsingToolbarLayout沒(méi)有設(shè)置collapsedTitleTextAppearance屬性,標(biāo)題可以正常顯示,然而到了24.1.0版本,即上面所用的版本,如果沒(méi)有設(shè)置collapsedTitleTextAppearance屬性,則當(dāng)toolbar收縮后,其標(biāo)題文字變得非常小。所以我們要設(shè)置collapsedTitleTextAppearance=”@style/TextAppearance.AppCompat.Title”這個(gè)屬性,才能變得正常。
4、如果沒(méi)有為CollapsingToolbarLayout設(shè)置一個(gè)title,那么會(huì)使用ActionBar自帶的標(biāo)題來(lái)顯示應(yīng)用的名稱(chēng),這是因?yàn)檎{(diào)用了setSupportActionBar(toolbar)函數(shù)。
最后附上代碼的地址:DesignSupportLibrarySample
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android 安全加密:對(duì)稱(chēng)加密詳解
本文主要介紹Android 安全加密對(duì)稱(chēng)加密,這里整理了詳細(xì)的資料及介紹凱撒密碼和對(duì)稱(chēng)密碼的資料,有興趣的小伙伴可以參考下2016-09-09Android代碼實(shí)現(xiàn)圖片和文字上下布局
在Android開(kāi)發(fā)中經(jīng)常會(huì)需要用到帶文字和圖片的button,下面來(lái)給大家介紹使用radiobutton實(shí)現(xiàn)圖片和文字上下布局或左右布局。感興趣的朋友一起學(xué)習(xí)吧2015-11-11android全屏去掉title欄的多種實(shí)現(xiàn)方法
android全屏去掉title欄包括以下幾個(gè)部分:實(shí)現(xiàn)應(yīng)用中的所有activity都全屏/實(shí)現(xiàn)單個(gè)activity全屏/實(shí)現(xiàn)單個(gè)activity去掉title欄/自定義標(biāo)題內(nèi)容/自定義標(biāo)題布局等等感興趣的可參考下啊2013-02-02Android 使用幀動(dòng)畫(huà)內(nèi)存溢出解決方案
這篇文章主要介紹了Android 使用幀動(dòng)畫(huà)內(nèi)存溢出解決方案的相關(guān)資料,這里提供了詳細(xì)的解決辦法,具有參考價(jià)值,需要的朋友可以參考下2016-12-12Android高亮引導(dǎo)控件的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android高亮引導(dǎo)控件的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07Android組件DrawerLayout仿網(wǎng)易新聞v4.4側(cè)滑菜單
這篇文章主要為大家詳細(xì)介紹了Android組件DrawerLayout仿網(wǎng)易新聞v4.4側(cè)滑菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01Fiddler實(shí)現(xiàn)手機(jī)抓包之小白入門(mén)必看
這篇文章主要介紹了Fiddler實(shí)現(xiàn)手機(jī)抓包之小白入門(mén)必看篇,需要的朋友可以參考下2018-03-03Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03