MD - 簡單控件使用以及自定義Behavior

1.概述

??Material Design從Android5.0開始引入的,是一種全新的設(shè)計語言(翻譯為“原材料設(shè)計”),其實是谷歌提倡的一種設(shè)計風(fēng)格岸蜗、理念、原則绊袋。最近發(fā)現(xiàn)現(xiàn)在很多 app 包括最早的知乎沒有使用了毕匀,今天再來回顧一下控件的簡單使用,效果非常簡單癌别,先上張圖皂岔。

????效果展示
????????????????

在這里插入圖片描述

2.控件介紹

??2.1 CoordinatorLayout:用來協(xié)調(diào)子控件,結(jié)合AppBarLayout展姐,F(xiàn)loatingActionButton等使用
??2.2 SwipeRefreshLayout:提供的下拉刷新的效果躁垛,里面只能包一個子控件可以包任意控件RecyclerView,ScrollView 圾笨,ListView教馆。
??2.3 ToolBar:加強版的ActionBar
??2.4 TabLayout:導(dǎo)航書簽,可以結(jié)合ViewPager使用
        app:tabIndicatorColor            導(dǎo)航書簽下方指示線的顏色
        app:tabIndicatorHeight           指示線的高度
        app:tabSelectedTextColor         導(dǎo)航書簽選中時的字體顏色
        app:tabMode="fixed"              顯示模式
                    1:fixed             全部展示
                    2. scrollable        滑動展示
??2.5 CollapsingToolBarLayout:折疊布局擂达,結(jié)合ToolBar使用
        android:minHeight                    最小高度
        app:layout_scrollFlags               模式
                    scroll                   想滾動就必須設(shè)置這個土铺。
                    enterAlways              實現(xiàn)quick return效果, 當(dāng)向下移動時,立即顯示View(比如Toolbar)板鬓。
                    exitUntilCollapsed       向上滾動時收縮View悲敷,但可以固定Toolbar一直在上面。
                    enterAlwaysCollapsed     當(dāng)你的View已經(jīng)設(shè)置minHeight屬性又使用此標(biāo)志時俭令,你的View只能以最小高度進入后德,只有當(dāng)滾動視圖到達頂部時才擴大到完整高度。
        app:contentScrim                     當(dāng)完全CollapsingToolbarLayout折疊(收縮)后的背景顏色抄腔。
        app:expandedTitleGravity             Toolbar的title顯示位置
        app:expandedTitleMargin              設(shè)置顯示位置設(shè)置Margin值
        app:layout_collapseParallaxMultiplier視差因子   0-1之間
        app:layout_collapseMode              視差模式
                    pin:·                    固定模式
                    parallax:                折疊效果
??2.6 SnackBar:MD風(fēng)格的Toast瓢湃,底部彈出
??2.7 TextInputLayout:自帶錯誤提示的文本框

??等等蒲跨,不一一介紹了,今天只是簡單的使用勋又,想了解噪径,可以去官網(wǎng)查看

3.效果實現(xiàn)

??3.1 CoordinatorLayout 和 Behavior 介紹

????CoordinatorLayout是什么? 看一下官方的介紹:Interaction behavior plugin for child views of (子視圖的交互行為插件)
????Behavior 實現(xiàn)了用戶的一個或者多個交互行為藏雏,它們可能包括拖拽拷况、滑動、快滑或者其他一些手勢掘殴。Behavior 是一個頂層抽象類赚瘦,其他的一些具體行為的 Behavior 都是繼承自這個類。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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:orientation="vertical"
        tools:context=".one_18.BehaviorActivity">
    
        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="@color/blue"
                app:layout_scrollFlags="scroll|enterAlways|snap"/>
    
    <!--        <androidx.appcompat.widget.Toolbar-->
    <!--            android:id="@+id/tool_bar"-->
    <!--            android:layout_width="match_parent"-->
    <!--            android:layout_height="wrap_content"-->
    <!--            app:title="知乎首頁"-->
    <!--            app:titleTextColor="#ffffff"-->
    <!--            app:layout_scrollFlags="scroll|enterAlways|snap">-->
    <!--        </androidx.appcompat.widget.Toolbar>-->
        </com.google.android.material.appbar.AppBarLayout>
    
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
        
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_marginBottom="70dp"
            android:layout_marginRight="16dp"
            android:layout_marginEnd="16dp"
            app:layout_behavior=".one_18.TranslationBehavior"
            android:src="@mipmap/ic_launcher">
        </com.google.android.material.floatingactionbutton.FloatingActionButton>
    
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:orientation="horizontal"
            android:background="@android:color/white"
            app:layout_behavior="@string/bottom_sheet_behavior">
    
            <ImageView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:src="@mipmap/ic_launcher"/>
            <ImageView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:src="@mipmap/ic_launcher"/>
            <ImageView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:src="@mipmap/ic_launcher"/>
            <ImageView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:src="@mipmap/ic_launcher"/>
        </LinearLayout>
    
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    </LinearLayout>

看一下Behaviror的方法作用

 /**
     * 表示是否給應(yīng)用了Behavior 的View 指定一個依賴的布局奏寨,通常起意,當(dāng)依賴的View 布局發(fā)生變化時
     * 不管被被依賴View 的順序怎樣,被依賴的View也會重新布局
     * @param parent
     * @param child 綁定behavior 的View
     * @param dependency   依賴的view
     * @return 如果child 是依賴的指定的View 返回true,否則返回false
     */
    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return super.layoutDependsOn(parent, child, dependency);
    }

    /**
     * 當(dāng)被依賴的View 狀態(tài)(如:位置病瞳、大欣抗尽)發(fā)生變化時,這個方法被調(diào)用
     * @param parent
     * @param child
     * @param dependency
     * @return
     */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        return super.onDependentViewChanged(parent, child, dependency);
    }

    /**
     *  當(dāng)coordinatorLayout 的子View試圖開始嵌套滑動的時候被調(diào)用套菜。當(dāng)返回值為true的時候表明
     *  coordinatorLayout 充當(dāng)nested scroll parent 處理這次滑動亲善,需要注意的是只有當(dāng)返回值為true
     *  的時候,Behavior 才能收到后面的一些nested scroll 事件回調(diào)(如:onNestedPreScroll逗柴、onNestedScroll等)
     *  這個方法有個重要的參數(shù)nestedScrollAxes蛹头,表明處理的滑動的方向。
     *
     * @param coordinatorLayout 和Behavior 綁定的View的父CoordinatorLayout
     * @param child  和Behavior 綁定的View
     * @param directTargetChild
     * @param target
     * @param nestedScrollAxes 嵌套滑動 應(yīng)用的滑動方向戏溺,看 {@link ViewCompat#SCROLL_AXIS_HORIZONTAL},
     *                         {@link ViewCompat#SCROLL_AXIS_VERTICAL}
     * @return
     */
    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    }

    /**
     * 嵌套滾動發(fā)生之前被調(diào)用
     * 在nested scroll child 消費掉自己的滾動距離之前渣蜗,嵌套滾動每次被nested scroll child
     * 更新都會調(diào)用onNestedPreScroll。注意有個重要的參數(shù)consumed旷祸,可以修改這個數(shù)組表示你消費
     * 了多少距離耕拷。假設(shè)用戶滑動了100px,child 做了90px 的位移,你需要把 consumed[1]的值改成90托享,
     * 這樣coordinatorLayout就能知道只處理剩下的10px的滾動斑胜。
     * @param coordinatorLayout
     * @param child
     * @param target
     * @param dx  用戶水平方向的滾動距離
     * @param dy  用戶豎直方向的滾動距離
     * @param consumed
     */
    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
    }

    /**
     * 進行嵌套滾動時被調(diào)用
     * @param coordinatorLayout
     * @param child
     * @param target
     * @param dxConsumed target 已經(jīng)消費的x方向的距離
     * @param dyConsumed target 已經(jīng)消費的y方向的距離
     * @param dxUnconsumed x 方向剩下的滾動距離
     * @param dyUnconsumed y 方向剩下的滾動距離
     */
    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
    }

    /**
     *  嵌套滾動結(jié)束時被調(diào)用,這是一個清除滾動狀態(tài)等的好時機嫌吠。
     * @param coordinatorLayout
     * @param child
     * @param target
     */
    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
        super.onStopNestedScroll(coordinatorLayout, child, target);
    }

    /**
     * onStartNestedScroll返回true才會觸發(fā)這個方法止潘,接受滾動處理后回調(diào),可以在這個
     * 方法里做一些準(zhǔn)備工作辫诅,如一些狀態(tài)的重置等凭戴。
     * @param coordinatorLayout
     * @param child
     * @param directTargetChild
     * @param target
     * @param nestedScrollAxes
     */
    @Override
    public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    }

    /**
     * 用戶松開手指并且會發(fā)生慣性動作之前調(diào)用,參數(shù)提供了速度信息炕矮,可以根據(jù)這些速度信息
     * 決定最終狀態(tài)么夫,比如滾動Header者冤,是讓Header處于展開狀態(tài)還是折疊狀態(tài)。返回true 表
     * 示消費了fling.
     *
     * @param coordinatorLayout
     * @param child
     * @param target
     * @param velocityX x 方向的速度
     * @param velocityY y 方向的速度
     * @return
     */
    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
    }

    /**
     * 擺放子 View 的時候調(diào)用档痪,可以重寫這個方法對子View 進行重新布局
     */
    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
        return super.onLayoutChild(parent, child, layoutDirection);
    }
??3.2 自定義 Behavior 來實現(xiàn) FloatingActionBar 的改變
    public class TranslationBehavior<T extends FloatingActionButton> extends CoordinatorLayout.Behavior<T> {
        private static final String TAG = "TranslationBehavior";
        
        /**
         * FloatingActionButton當(dāng)前是否是顯示狀態(tài)
         */
        private boolean isOut = false;
    
        public TranslationBehavior(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        /**
         *  注意:當(dāng)coordinatorLayout 的子View試圖開始嵌套滑動的時候被調(diào)用涉枫。當(dāng)返回值為true的時候表明
         *  coordinatorLayout 充當(dāng)nested scroll parent 處理這次滑動,需要注意的是只有當(dāng)返回值為true
         *  的時候腐螟,Behavior 才能收到后面的一些nested scroll 事件回調(diào)(如:onNestedPreScroll愿汰、onNestedScroll等)
         *  這個方法有個重要的參數(shù)nestedScrollAxes,表明處理的滑動的方向乐纸。
         * @param coordinatorLayout 和Behavior 綁定的View的父CoordinatorLayout
         * @param child  和Behavior 綁定的View
         * @param directTargetChild
         * @param target
         * @param axes 嵌套滑動,滑動方向衬廷, {@link ViewCompat#SCROLL_AXIS_HORIZONTAL}
         *                                 {@link ViewCompat#SCROLL_AXIS_VERTICAL}
         * @return
         */
        @Override
        public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull T child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
            Log.e(TAG,"onStartNestedScroll");
            return axes == ViewCompat.SCROLL_AXIS_VERTICAL;
        }
    
    
        /**
         * 進行嵌套滾動時被調(diào)用
         * @param coordinatorLayout
         * @param child
         * @param target
         * @param dxConsumed    target 已經(jīng)消費的x方向的距離
         * @param dyConsumed    target 已經(jīng)消費的y方向的距離  往上滑是正  往下滑是負(fù)
         * @param dxUnconsumed  x 方向剩下的滾動距離
         * @param dyUnconsumed  y 方向剩下的滾動距離
         * @param type
         */
        @Override
        public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull T child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
            Log.e(TAG,"onNestedScroll");
            super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
            Log.e(TAG,"dyConsumed:"+dyConsumed+"--------dyUnconsumed:"+dyUnconsumed);
            //1.將我們的child(FloatingActionButton)進行隱藏
            if (dyConsumed > 0){
                if (!isOut){
                    //2.移動距離計算  bottomMargin + 自己的高度
                    int translationY = ((CoordinatorLayout.LayoutParams)child.getLayoutParams()).bottomMargin + child.getMeasuredHeight();
                    child.animate().translationY(translationY).setDuration(500).start();
                    //3.注意:這樣設(shè)置后網(wǎng)上滑的時候會發(fā)現(xiàn)FloatingActionButton會反應(yīng)慢,我們可以設(shè)置一個標(biāo)志位
                    isOut = true;
                }
            }else {
                if (isOut){
                    child.animate().translationY(0).setDuration(500).start();
                    isOut = false;
                }
            }
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汽绢,一起剝皮案震驚了整個濱河市吗跋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宁昭,老刑警劉巖跌宛,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異积仗,居然都是意外死亡秩冈,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門斥扛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丹锹,你說我怎么就攤上這事稀颁。” “怎么了楣黍?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵匾灶,是天一觀的道長。 經(jīng)常有香客問我租漂,道長阶女,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任哩治,我火速辦了婚禮秃踩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘业筏。我一直安慰自己憔杨,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布蒜胖。 她就那樣靜靜地躺著消别,像睡著了一般抛蚤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寻狂,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天岁经,我揣著相機與錄音,去河邊找鬼蛇券。 笑死缀壤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怀读。 我是一名探鬼主播诉位,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼菜枷!你這毒婦竟也來了苍糠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤啤誊,失蹤者是張志新(化名)和其女友劉穎岳瞭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚊锹,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡瞳筏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了牡昆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姚炕。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖丢烘,靈堂內(nèi)的尸體忽然破棺而出柱宦,到底是詐尸還是另有隱情,我是刑警寧澤播瞳,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布掸刊,位于F島的核電站,受9級特大地震影響赢乓,放射性物質(zhì)發(fā)生泄漏忧侧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一牌芋、第九天 我趴在偏房一處隱蔽的房頂上張望蚓炬。 院中可真熱鬧,春花似錦躺屁、人聲如沸试吁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熄捍。三九已至烛恤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間余耽,已是汗流浹背缚柏。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碟贾,地道東北人币喧。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像袱耽,于是被迫代替她去往敵國和親杀餐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353