MaterialDesign系列文章(七)AppbarLayout的使用

筆墨Android發表於2019-02-26

大家好我是筆墨Android,曾經的我總是迷茫的,不知道怎麼學習才是最好的!但是最近我聽到我對一句話,對我特別又感觸
做好現在能做的,你會慢慢的發現你在改變! 誰都有改變自己的權力,就看你是否想要去改變!其實我們每天只要做一點點的改變,會從量到質改變!今天說的有些寒酸了,但是自從我開始認真的寫部落格,我發現我的生活正慢慢改變著!

此圖片來源於網路

今天聊點什麼呢?上篇文章講到了MaterialDesign系列文章(六)CoordinatorLayout的一些聯動,其中提到了很多關於MaterialDesign的控制元件,但是隻是一筆帶過了,沒有具體的分析,為了讓小夥伴們能更好的理解!所以我覺得有必要單獨講講每一控制元件!今天就先從AppBarLayout開始吧!

本文知識點:

  • AppBarLayout是什麼?能用來幹什麼?
  • AppBarLayout的一些使用案例。

1.AppBarLayout是什麼?能用來幹什麼?

AppBarLayout is a vertical LinearLayout which implements many of the features of material designs app bar concept, namely scrolling gestures.Children should provide their desired scrolling behavior through setScrollFlags(int) and the associated layout xml attribute: app:layout_scrollFlags.This view depends heavily on being used as a direct child within a CoordinatorLayout. If you use AppBarLayout within a different ViewGroup, most of it`s functionality will not work.

我用人話翻譯一下啊!AppBarLayout繼承LinearLayout,可以響應使用者的手勢操作,但是必須在CoordinatorLayout下使用,否則會有許多功能使用不了。

其實說到AppBarLayout你能想到什麼?其實最開始我想到也只有聯動,沒有別的,但是關於AppBarLayout的聯動你真的知道嗎?相信看了上一篇文章的人都會覺得,AppBarLayout總是和TabLayout,CollapsingToolbarLayout聯動。其實AppBarLayout的用處遠遠不止這些?還有的就是套路。。。

MaterialDesign系列文章(七)AppbarLayout的使用

2. AppBarLayout的使用!

相信看了上一篇文章的小夥伴都知道了AppBarLayout怎麼和CoordinatorLayout、CollapsingToolbarLayout、TabLayout聯動,往往AppBarLayout的出現頻率和CoordinatorLayout、CollapsingToolbarLayout、TabLayout時一樣的,也就是說基本上講的都是它們怎麼聯動!但是其實Toolbar不是非要和他們連用的。它可以自己和自己玩。。。而且玩的還很開心!當你無聊的時候你可以拿他當豎直的LinearLayout使用,心情好了你可以和CoordinatorLayout、TabLayout一起用。像我這種既無聊又心情好的時候我就自己玩。哈哈,扯遠了。讓我們看看它是怎麼自(。・∀・)ノ゙嗨的吧!先來一張效果圖…

錄得不好多見諒

其實你仔細看看這個效果是不是很常見的吸頂效果!這種效果在電商的首頁比較多見。其實也是很好實現的,這裡簡單拿佈局說一下吧!

<?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"
    tools:context="com.jinlong.newmaterialdesign.material.AppBarLayoutActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#e79349"
            android:gravity="center"
            android:scaleType="center"
            android:text="這裡可以放ViewPager"
            android:textColor="@android:color/white"
            android:textSize="20sp"
            app:layout_scrollFlags="scroll" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:overScrollMode="never"
            android:scrollbars="none"
            app:layout_scrollFlags="scroll" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#009988"
            android:gravity="center"
            android:text="這裡時需要吸頂的效果內容,可以是任何內容的"
            android:textColor="@android:color/white" />

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

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">


        <LinearLayout
            android:id="@+id/ll_bottom"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:gravity="center"
                android:text="底部還有內容啊!!!" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009988"
                android:gravity="center"
                android:text="標籤1" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#002288"
                android:gravity="center"
                android:text="標籤2" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#009922"
                android:gravity="center"
                android:text="標籤3" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#00aa88"
                android:gravity="center"
                android:text="標籤4" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#999988"
                android:gravity="center"
                android:text="標籤5" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
複製程式碼

這個內容主要是依託於app:layout_scrollFlags="scroll"來實現一些你想要的效果,你可以設定不同的佈局,來得到你想要的內容!

重點來了!!!
AppBarLayout的監聽,之前在文章中講到AppBarLayout和CoordinatorLayout、CollapsingToolbarLayout、TabLayout聯動的問題,今天測試來了提出一個問題,說聯動的時候標題的文字,說聯動時候的那個動畫太難看,做簡單一點,直接漸變的顯示多好!

MaterialDesign系列文章(七)AppbarLayout的使用

然後我就默默的掏出了手機,開啟付款嗎,來你先掃一下我們倆在繼續說!!!結果人家真的掃了,不過給我我一分錢。。。當時我是崩潰的,但是話都說出去了。別鼓掌,要臉。。。接下來就有下面的內容了!其實AppBarLayouot是有關於這個監聽的,沒有的話我也不會這麼就答應了,小哥哥是不打沒有準備的仗的!哈哈。。。

        AppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                //偏移量的計算
            }
        });
複製程式碼

這個監聽,給我們返回了響應的滑動變化量,我們可以根據總高度,然後根據變化量算出一個比例,就可以很好的計算出應該設定的透明度了!其實有了這個偏移量加個什麼動畫也是可以的嘛!請大家冥想一分鐘,看看有沒有思路。馬上給出答案。。。。先來張圖走一波!

這個效果進攻娛樂,只是設定了TextView的旋轉屬性從而進行計算,只是給大家帶來個思路,所以別局限於我講的內容,要融匯貫通!

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

                //這個是計算App bar Layout的總高度的API
                int totalScrollRange = appBarLayout.getTotalScrollRange();

                float ratio = Math.abs((float) verticalOffset / totalScrollRange);

                mTvTitle.setRotation(ratio * 360);
            }
        });
複製程式碼
圖片效果僅供娛樂

這裡有一點要說明一下,就是有關於滑動方向的,向上滑動為負值。向下滑動為正值。所以這裡使用的是絕對值進行計算的。還有一點就是剛開始進來的時候會走一次回撥,計算出來的結果是0,所以設定透明度的時候,應該注意這裡。因為總體的比值不會大於1,所以剛開始的時候你要是想看見它的,設定透明度的取反就可以了也就是 (1-比值) 就可以了!程式碼是這樣的!

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

                //這個是計算App bar Layout的總高度的API
                int totalScrollRange = appBarLayout.getTotalScrollRange();

                float ratio = Math.abs((float) verticalOffset / totalScrollRange);

                mTvTitle.setAlpha(1 - ratio);

                Log.e(TAG, "onOffsetChanged: " + ratio + "---" + verticalOffset);
            }
        });
複製程式碼

就不上圖了,具體看你們的需求了。我們當時的需求就是,Toolbar在上面,全部摺疊的時候才顯示出來。要是處於開啟狀態的話就不現實!和這個大同小異,只要你算好比值就可以了!在給你們點福利!

public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {
 
    public enum State {
        EXPANDED,
        COLLAPSED,
        IDLE
    }
 
    private State mCurrentState = State.IDLE;
 
    @Override
    public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
        if (i == 0) {
            if (mCurrentState != State.EXPANDED) {
                onStateChanged(appBarLayout, State.EXPANDED);
            }
            mCurrentState = State.EXPANDED;
        } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
            if (mCurrentState != State.COLLAPSED) {
                onStateChanged(appBarLayout, State.COLLAPSED);
            }
            mCurrentState = State.COLLAPSED;
        } else {
            if (mCurrentState != State.IDLE) {
                onStateChanged(appBarLayout, State.IDLE);
            }
            mCurrentState = State.IDLE;
        }
    }
 
    public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}
複製程式碼

    mAppBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
            @Override
            public void onStateChanged(AppBarLayout appBarLayout, State state) {
                Log.d("STATE", state.name());
                if( state == State.EXPANDED ) {
                    
                    //展開狀態
                    
                }else if(state == State.COLLAPSED){
                    
                    //摺疊狀態
                     
                }else {
                
                    //中間狀態
                
                }
            }
        });
複製程式碼

這個是判斷AppBarLayout展開於摺疊狀態的。怎麼用我就不說了!今天的分享就到這裡吧!內容不多,希望大家過一個愉快的週末!!!作為程式設計師的我們週末多出去溜達一下,找找妹子,單身狗的世界是沒有色彩的。。。


說兩句題外話,我覺得學習這個東西,應該有自己的體系。其實我也總在想,怎麼寫文章你們才能記住,包括我自己也是,有的時候用的話也要回來看看部落格才能想起一些內容的用法。最近有小夥伴說文章太多了,看不完。其實我也在想,怎麼才能最簡單的把這些內容介紹給大家!簡短的怕你不理解,太長的怕你看不完…希望小夥盤們提出你們的想法,我會及時改進的!!!

相關文章