Android CollapsingToolbarLayout 和ToolBar多種實踐

項目原因導致關于Toolbar的實踐筆記一拖再拖…都快忘記實現的過程了( - - ! )。之前粗略用過CollapsingToolbarLayout 記錄自己實現的簡便版的RecyclerView,不過項目中再次用到的時候還有不少磕磕絆絆。

效果:

first.gif

布局

頭部背景是我隨便切的一個圖片孝冒。首先明確一點:整體伸縮布局是包裹在CoordinatorLayout中的,并且非頭部的部分朴皆,不論是FrameLayout還是RecyclerView或者其他的View秩冈,都需要添加屬性:app:layout_behavior="@string/appbar_scrolling_view_behavior"

  • 這里展開一點題外話,我們在網上尋找到的CoordinatorLayout的相關資料,可能一般看到的基本XML布局是這樣的:
<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=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

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

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

其中CoordinatorLayout用到的屬性:
android:fitsSystemWindows="true"
需要注意使用場景燥透。
可以看到圖中我用了多個Fragment,其他的部分Fragment的布局中我也同樣使用了android:fitsSystemWindows="true"這個屬性辨图,但是在項目全局的主題中班套,我已經設置了"no titlebar"。設置以上屬性以后故河,會導致狀態(tài)欄會自動調整view的padding以便給system windows留出空間吱韭,多個同級布局使用此參數,將導致 切換過程布局抖動鱼的。
我建議如已經隱掉系統(tǒng)的titlebar的布局或者Activity理盆,就無需設置這個屬性了。
這里有個關于設置android:fitsSystemWindows屬性的效果圖凑阶,可以看一下:fitsSystemWindows

我們接著來看整體布局:

<?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:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#66ffffff">
        <!-- 頭部的布局 -->
    </android.support.design.widget.AppBarLayout>
<!-- 主題的布局 -->
    <com.jinqiang.RecyclerViewRefresh.IRecyclerView
        android:id="@+id/recyclerview"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</android.support.design.widget.CoordinatorLayout>

不論主題布局的層級如何猿规,設置app:layout_behavior="@string/appbar_scrolling_view_behavior"就可以使CoordinatorLayout計算滑動子view了。

toolbar

toolbar 中的頭部布局晌砾,要控制哪塊布局是需要滑動效果坎拐,哪些是不需要的,這里有個XML對屬性的說明比較清晰:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 為了使得Toolbar有滑動效果,必須做到如下三點:
          CoordinatorLayout必須作為整個布局的父布局容器哼勇。
          給需要滑動的組件設置 app:layout_scrollFlags=”scroll|enterAlways” 屬性都伪。
          給你的可滑動的組件,也就是RecyclerView 或者 NestedScrollView积担、ListView陨晶,ScrollView等設置如下屬性:
           app:layout_behavior="@string/appbar_scrolling_view_behavior"-->


    <!--默認的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的內容都作為AppBar
        此處將Toolbar 和Tablayout的組合部分共同構成 AppBar的效果帝璧。
        注意: AppBarLayout必須作為Toolbar的父布局容器;
        AppBarLayout是支持手勢滑動效果的先誉,不過的跟CoordinatorLayout配合使用;-->
    <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">

        <!--設置的layout_scrollFlags有如下幾種選項:
             scroll: 所有想滾動出屏幕的view都需要設置這個flag- 沒有設置這個flag的view將被固定在屏幕頂部。
             enterAlways: 這個flag讓任意向下的滾動都會導致該view變?yōu)榭梢姷乃福瑔⒂每焖佟胺祷啬J健薄?             enterAlwaysCollapsed: 當你的視圖已經設置minHeight屬性又使用此標志時褐耳,你的視圖只能已最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度渴庆。
             exitUntilCollapsed: 滾動退出屏幕铃芦,最后折疊在頂端。-->
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            app:tabIndicatorColor="@color/white"
            app:tabSelectedTextColor="@color/gray"
            app:tabTextColor="@color/white"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </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.CoordinatorLayout>

圖中我的實例中頭部有三個布局:

<android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#66ffffff"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:expandedTitleMarginStart="48dp"
            android:background="@mipmap/rectangle"
            app:expandedTitleMarginEnd="64dp">
            <android.support.design.widget.TabLayout
                android:id="@+id/tab"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:tabTextColor="#ffffff"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.8"
                android:layout_marginTop="120dp"
                android:paddingBottom="15dp"
                />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:contentInsetLeft="0dp"
                app:contentInsetStart="0dp"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin">
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
                    <LinearLayout
                        android:id="@+id/toolbar1"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent">
                        <TextView
                            android:id="@+id/layout1_tv"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:gravity="center"
                            android:text="布局一"
                            android:textColor="#ffffff"
                            android:textSize="20sp"/>
                    </LinearLayout>
                    <LinearLayout
                        android:id="@+id/toolbar2"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:orientation="horizontal"
                        android:visibility="gone">
                        <TextView
                            android:id="@+id/layout2_tv1"
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:gravity="center"
                            android:text="布局二"
                            android:textColor="#ffffff"
                            android:textSize="20sp"/>
                        <TextView
                            android:id="@+id/layout2_tv2"
                            android:layout_width="wrap_content"
                            android:layout_height="match_parent"
                            android:gravity="center"
                            android:text="布局二"
                            android:layout_marginLeft="20dp"
                            android:textColor="#ffffff"
                            android:textSize="20sp"/>
                    </LinearLayout>
                </RelativeLayout>
            </android.support.v7.widget.Toolbar>

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

TabLayout中的第三個布局是我需要實現滑動效果的

布局三

設置的layout_scrollFlags有如下幾種選項:

  • scroll: 所有想滾動出屏幕的view都需要設置這個flag- 沒有設置這個flag的view將被固定在屏幕頂部襟雷。
  • enterAlways: 這個flag讓任意向下的滾動都會導致該view變?yōu)榭梢娙凶遥瑔⒂每焖佟胺祷啬J健薄?/li>
  • enterAlwaysCollapsed: 當你的視圖已經設置minHeight屬性又使用此標志時,你的視圖只能已最小高度進入耸弄,只有當滾動視圖到達頂部時才擴大到完整高度咧虎。
  • exitUntilCollapsed: 滾動退出屏幕,最后折疊在頂端计呈。

接著基本頭部布局設置完成砰诵,需要完成的是頭部滑動完成以后,布局一和布局二的顯隱震叮。我們實現Appbarlayout的addOnOffsetChangedListener監(jiān)聽:

/** appbarLayout **/
        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if(verticalOffset == 0){
                    view1.setVisibility(View.VISIBLE);
                    view2.setVisibility(View.GONE);
                    //alpha 變化
                    setToolbar1Alpha(255);

                }else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()){
                    view1.setVisibility(View.GONE);
                    view2.setVisibility(View.VISIBLE);
                    //alpha 變化
                    setToolbar2Alpha(255);
                }else{
                    int alpha=255-Math.abs(verticalOffset);
                    if(alpha<0){
                        //收縮toolbar
                        view1.setVisibility(View.GONE);
                        view2.setVisibility(View.VISIBLE);
                        setToolbar2Alpha(Math.abs(verticalOffset));
                    }else{
                        //張開toolbar
                        view1.setVisibility(View.VISIBLE);
                        view2.setVisibility(View.GONE);
                        setToolbar1Alpha(alpha);
                    }
                }
            }
        });

布局是圖片的話胧砰,alpha變化就會有了。

項目地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末苇瓣,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子偿乖,更是在濱河造成了極大的恐慌击罪,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贪薪,死亡現場離奇詭異媳禁,居然都是意外死亡,警方通過查閱死者的電腦和手機画切,發(fā)現死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門竣稽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事毫别⊥薰” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵岛宦,是天一觀的道長台丛。 經常有香客問我,道長砾肺,這世上最難降的妖魔是什么挽霉? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮变汪,結果婚禮上侠坎,老公的妹妹穿的比我還像新娘。我一直安慰自己裙盾,他們只是感情好实胸,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闷煤,像睡著了一般童芹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鲤拿,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天假褪,我揣著相機與錄音,去河邊找鬼近顷。 笑死生音,一個胖子當著我的面吹牛,可吹牛的內容都是我干的窒升。 我是一名探鬼主播缀遍,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼饱须!你這毒婦竟也來了域醇?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蓉媳,失蹤者是張志新(化名)和其女友劉穎譬挚,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體酪呻,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡减宣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了玩荠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漆腌。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡贼邓,死狀恐怖,靈堂內的尸體忽然破棺而出闷尿,到底是詐尸還是另有隱情塑径,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布悠砚,位于F島的核電站晓勇,受9級特大地震影響,放射性物質發(fā)生泄漏灌旧。R本人自食惡果不足惜绑咱,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枢泰。 院中可真熱鬧描融,春花似錦、人聲如沸衡蚂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毛甲。三九已至年叮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玻募,已是汗流浹背只损。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留七咧,地道東北人跃惫。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像艾栋,于是被迫代替她去往敵國和親爆存。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容