Android MaterialDesign常用控件詳解

參考:
MD基礎控件簡書:https://www.jianshu.com/p/e2ae6aaff696
Behavior簡書:https://www.jianshu.com/p/82d18b0d18f4

MD常用控件詳解

Material Design中的一些常見控件的使用

ToolBar

Toolbar 是應用內的action bars的一個歸納。
Toolbar使用來替代原來的ActionBar的就行了。
Toolbar是一個ViewGroup容器!

  1. Navigation Button
  2. Logo Image
  3. title
  4. subtitle
  5. 一個或多個自定義的View
  6. Action Menu
    在這裏插入圖片描述
<?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=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:background="@color/colorPrimaryDark"
        android:gravity="center"
        app:navigationIcon="@mipmap/more"
        app:subtitle="下一步"
        app:subtitleTextColor="@android:color/white"
        app:title="首頁"
        app:titleTextColor="@android:color/white" />
</android.support.design.widget.CoordinatorLayout>
    private void initView() {
        toolbar = findViewById(R.id.toolbar);
        toolbar.inflateMenu(R.menu.layout_toolbar_menu);
        //點擊溢出菜單的點擊事件
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                return false;
            }
        });
        //點擊導航按鈕的點擊事件
        //toolbar.setNavigationOnClickListener();
    }

AppbarLayout

AppbarLayout繼承自LinearLayout,它就是一個垂直方向的LinearLayout,在LinearLayout的基礎上添加了一些材料設計的概念和特性,即滑動手勢。

它可以讓你定製在某個可滑動的View(如:ScrollView ,ListView ,RecyclerView 等)滑動手勢發生改變時,內部的子View 該做什麼動作。子View應該提供滑動時他們期望的響應的動作Behavior,通過setScrollFlags(int),或者xml中給需要滑動的子控件使用屬性app:layout_scrollFlags=“”。layout_scrollFlags屬性中的幾個屬性(對應的是AppbarLayout中Behavior的一些邏輯處理)

AppbarLayout中的layout_scrollFlags幾個參數:

  • scroll
    子View添加layout_scrollFlags屬性的值scroll時,這個View將會隨着可滾動View(如:ScrollView)一起滾動,就好像子View是屬於ScrollView的一部分一樣。

  • enterAlways
    子View添加layout_scrollFlags屬性的值有enterAlways時, 當滑動控件向下滑動時,子View將直接向下滑動,而不管滑動控件是否在滑動。注意:要與滑動控件搭配使用,否者是不能滑動的。

  • enterAlwaysCollapsed
    enterAlwaysCollapsed是對enterAlways的補充,當滑動控件向下滑動的時候,滑動View(也就是設置了enterAlwaysCollapsed 的View)下滑至摺疊的高度,當滑動控件到達滑動範圍的結束值的時候,滑動View剩下的部分開始滑動。這個摺疊的高度是通過View的minimum height (最小高度)指定的。

  • exitUntilCollapsed
    當滑動控件滑出屏幕時(也就是向上滑動時),滑動View先響應滑動事件,滑動至摺疊高度,也就是通過
    minimum height 設置的最小高度後,就固定不動了,再把滑動事件交給 scrollview 繼續滑動。

  • snap
    在滾動結束後,如果view只是部分可見,它將滑動到最近的邊界。比如,如果view的底部只有25%可見,它將
    滾動離開屏幕,而如果底部有75%可見,它將滾動到完全顯示。

<?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">
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="@color/colorAccent"
            android:gravity="bottom"
            android:minHeight="50dp"
            android:text="首頁"
            app:layout_scrollFlags="scroll|snap" />
    </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">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="111" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="222" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="333" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="444" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="555" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="666" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="777" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

TabLayout

TabLayout是Tab控件的容器,封裝了多個操作Tab控件的屬性,
能讓不同視圖和功能之間的切換變得簡單。

Tab的大多屬性是在TabLayout中進行設值:

  1. app:tabIndicatorColor 設置指示器的顏色(默認情況下指示器的顏色爲colorAccent)
  2. app:tabIndicatorHeight 設置指示器的高度,Material Design 規範建議是2dp
  3. app:tabMaxWidth 設置 Tab 的最大寬度
  4. app:tabMinWidth 設置 Tab 的最小寬度
  5. app:tabMode 設置Tabs的顯示模式,有兩個常量值,MODE_FIXED,MODE_SCROLLABLE。用法:app:tabMode="fixed"或者app:tabMode=“scrollable”
  6. app:tabSelectedTextColor 設置Tab選中後,文字顯示的顏色
  7. app:tabTextColor 設置Tab未選中,文字顯示的顏色

在這裏插入圖片描述

<?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.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/white"
        app:tabGravity="center"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabIndicatorHeight="2dp"
        app:tabMode="fixed"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextColor="@android:color/black">

        <android.support.design.widget.TabItem
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="默認" />

        <android.support.design.widget.TabItem
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="銷量" />

        <android.support.design.widget.TabItem
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="價格" />
    </android.support.design.widget.TabLayout>
</android.support.design.widget.CoordinatorLayout>
    private void initView() {
        tabLayout = findViewById(R.id.tabLayout);
        //動態設置tabs
        tabLayout.addTab(tabLayout.newTab().setText("綜合"));
        tabLayout.addTab(tabLayout.newTab().setText("銷量"));
        tabLayout.addTab(tabLayout.newTab().setText("價格"));
        tabLayout.addOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //被選中 這個地方有個坑   點擊第一個 不會有變化  因爲第一個以及是選中狀態
                Log.e("DN_TAB_0----->",tab.getText().toString()+"");
            }
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                //被取消
                Log.e("DN_TAB_1----->",tab.getText().toString()+"");
            }
            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                //重複選中
                Log.e("DN_TAB_3----->",tab.getText().toString()+"");
            }
        });
    }

在這裏插入圖片描述

CollapsingToolbarLayout

CollapsingToolbarLayout是一個摺疊的Toolbar,它能夠設置一種顏色或者一張圖片來遮擋它裏面的內容。

推薦CoordinatorLayout + AppBarLayout + CollapsingToolbarLayout一起使用

  1. Collapsing title–>摺疊標題
  2. Content scrim–>內容紗布
  3. Status bar scrim–>狀態欄紗布
  4. Parallax scrolling children–>有視差地滾動子View
  5. Pinned position children–>固定子View的位置
<?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">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapse_layout"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@mipmap/timg"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/appbar_layout_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:navigationIcon="@mipmap/more"
                app:title="AppbarLayout"
                app:titleTextColor="@android:color/white" />
        </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">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="111" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="222" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="333" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="444" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="555" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="666" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="777" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
    private void initView() {
        final Toolbar toolbar = findViewById(R.id.appbar_layout_toolbar);
        //設置沉浸式狀態欄
        StatusBarUtils.setTranslucentImageHeader(this, 0, toolbar);
        //設置標題顏色
        toolbar.setTitleTextColor(Color.TRANSPARENT);
        //加載動作菜單
        toolbar.inflateMenu(R.menu.layout_toolbar_menu);
        AppBarLayout appBarLayout = findViewById(R.id.appbar_layout);

        final CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapse_layout);
        collapsingToolbarLayout.setTitle("");
        collapsingToolbarLayout.setCollapsedTitleTextColor(getResources().getColor(R.color.white));
        collapsingToolbarLayout.setExpandedTitleColor(getResources().getColor(R.color.white));
        collapsingToolbarLayout.setExpandedTitleColor(Color.TRANSPARENT);
        //設置紗布
        collapsingToolbarLayout.setContentScrimColor((getResources().getColor(R.color.colorAccent)));
        //監聽appBarLayout的偏移
        appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                    toolbar.setTitleTextColor(getResources().getColor(R.color.white));
                    collapsingToolbarLayout.setTitle("AppbarLayout");
                } else {
                    collapsingToolbarLayout.setTitle("");
                }
            }
        });
    }

在這裏插入圖片描述

CardView

CardView就是一個幀佈局,但是它裏面封裝了很多屬性,
包括圓角,陰影等。

  1. app:cardBackgroundColor–>卡片顏色
  2. app:cardCornerRadius–>卡片圓角
  3. app:cardElevation–>卡片陰影
  4. app:cardUseCompatPadding–>padding
    在這裏插入圖片描述
<?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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_marginBottom="0dp"
            android:clickable="true"
            android:foreground="?attr/selectableItemBackground"
            app:cardCornerRadius="10dp"
            app:cardElevation="3dp">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:scaleType="center"
                android:src="@mipmap/meizhi" />
        </android.support.v7.widget.CardView>

    </LinearLayout>

    <android.support.design.widget.BottomNavigationView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_gravity="bottom"
        app:menu="@menu/layout_toolbar_menu">

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

Behavior中的方法詳解

Behavior中的一些方法詳解

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * BeHavior常用的方法詳解
 */
public class MyBeHavior extends CoordinatorLayout.Behavior {
    //列表頂部和textView之間的距離
    private float deltaY;


    public MyBeHavior(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
    }

    /**
     * 表示是否給應用了Behavior 的View 指定一個觀察的佈局,通常,當觀察的View 佈局發生變化時
     * 不管被觀察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 dependency instanceof NestedScrollView;
    }

    /**
     * 當被觀察者的View 狀態(如:位置、大小)發生變化時,這個方法被調用
     *
     * @param parent
     * @param child
     * @param dependency
     * @return
     */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        if (deltaY == 0) {
            deltaY = dependency.getY() - child.getHeight();
        }
        //被觀察者View的Y座標  - 觀察者的高度  得到的就是兩者之間的距離
        float dy = dependency.getY() - child.getHeight();
        //如果兩者之間的距離小於0 就賦值爲0  如果兩者之間的距離不小於0  就將兩者之間的實際距離賦值給它
        dy = dy < 0 ? 0 : dy;
        //計算Y軸每次偏移的距離
        float y = -(dy / deltaY) * child.getHeight();
        Log.e("BEHAVIOR----->", y + "-------------");
        //將編譯距離設置給觀察者
        child.setTranslationY(y);
        return false;
    }

    /**
     * 當coordinatorLayout 的子View試圖開始嵌套滑動的時候被調用。當返回值爲true的時候表明
     * coordinatorLayout 充當nested scroll parent 處理這次滑動,需要注意的是隻有當返回值爲true
     * 的時候,Behavior 才能收到後面的一些nested scroll 事件回調(如:onNestedPreScroll、onNestedScroll等)
     * 這個方法有個重要的參數nestedScrollAxes,表明處理的滑動的方向。
     *
     * @param coordinatorLayout 和Behavior 綁定的View的父CoordinatorLayout
     * @param child             和Behavior 綁定的View  觀察者
     * @param directTargetChild
     * @param target
     * @param nestedScrollAxes  嵌套滑動 應用的滑動方向
     * @param type
     * @return
     */
    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild,
                                       View target, int nestedScrollAxes, int type) {
        child.setVisibility(View.GONE);
        return false;
    }


    /**
     * 嵌套滾動發生之前被調用
     * 在nested scroll child 消費掉自己的滾動距離之前,嵌套滾動每次被nested scroll child
     * 更新都會調用onNestedPreScroll。注意有個重要的參數consumed,可以修改這個數組表示你消費
     * 了多少距離。假設用戶滑動了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, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
    }


    /**
     * 進行嵌套滾動時被調用
     *
     * @param coordinatorLayout
     * @param child
     * @param target
     * @param dxConsumed        target 已經消費的x方向的距離
     * @param dyConsumed        target 已經消費的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, int type) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
    }

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

    /**
     * onStartNestedScroll返回true纔會觸發這個方法,接受滾動處理後回調,可以在這個
     * 方法裏做一些準備工作,如一些狀態的重置等。
     *
     * @param coordinatorLayout
     * @param child
     * @param directTargetChild
     * @param target
     * @param nestedScrollAxes
     */
    @Override
    public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild,
                                       View target, int nestedScrollAxes, int type) {
        super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes, type);
    }

    /**
     * 用戶鬆開手指並且會發生慣性動作之前調用,參數提供了速度信息,可以根據這些速度信息
     * 決定最終狀態,比如滾動Header,是讓Header處於展開狀態還是摺疊狀態。返回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 進行重新佈局
    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
        return super.onLayoutChild(parent, child, layoutDirection);
    }

    /**
     * 是否攔截觸摸
     *
     * @param parent
     * @param child
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull MotionEvent ev) {
        return super.onInterceptTouchEvent(parent, child, ev);
    }
}

自定義Behavior示例

public class BehaviorTest extends CoordinatorLayout.Behavior {
    // 列表頂部和滾動控件的距離
    private float deltaY;


    public BehaviorTest(Context context, AttributeSet attributeSet){
        super(context,attributeSet);
    }

    /**
     * 表示是否給應用了Behavior 的View 指定一個觀察的佈局,通常,當觀察的View 佈局發生變化時
     * 不管被觀察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) {
        if(dependency instanceof NestedScrollView || dependency instanceof Button){
            return true;
        }
        return false;
    }


    /**
     * 當被觀察者的View 狀態(如:位置、大小)發生變化時,這個方法被調用
     * @param parent
     * @param child
     * @param dependency
     * @return
     */
    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        //一開始  等於0
        if (deltaY == 0) {
            //初始化兩者之間的距離
            deltaY = dependency.getY() - child.getHeight();
        }
        Log.e("DN deltaY------------>",deltaY+"------------");
        //被觀察者View的Y座標 - 觀察者的高度  得到兩者之間剩餘的距離
        float dy = dependency.getY() - child.getHeight();
        //如果距離小於0  就賦值0  如果距離大於等於0  就把剩餘距離賦值給它
        dy = dy < 0 ? 0 : dy;
        //計算Y軸每次偏移的距離
        float y = -(dy / deltaY) * child.getHeight();
        Log.e("DN-------------->",y+"------------");
        //設置Y軸的偏移參數
        child.setTranslationY(y);
        return true;
    }

    /**
     *  當coordinatorLayout 的子View試圖開始嵌套滑動的時候被調用。當返回值爲true的時候表明
     *  coordinatorLayout 充當nested scroll parent 處理這次滑動,需要注意的是隻有當返回值爲true
     *  的時候,Behavior 才能收到後面的一些nested scroll 事件回調(如:onNestedPreScroll、onNestedScroll等)
     *  這個方法有個重要的參數nestedScrollAxes,表明處理的滑動的方向。
     *
     * @param coordinatorLayout 和Behavior 綁定的View的父CoordinatorLayout
     * @param child  和Behavior 綁定的View  觀察者
     * @param directTargetChild
     * @param target
     * @param nestedScrollAxes 嵌套滑動 應用的滑動方向
     * @param type
     *
     * @return
     */
    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild,
                                       View target, int nestedScrollAxes, int type) {
        return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes,type);
    }


    /**
     * 嵌套滾動發生之前被調用
     * 在nested scroll child 消費掉自己的滾動距離之前,嵌套滾動每次被nested scroll child
     * 更新都會調用onNestedPreScroll。注意有個重要的參數consumed,可以修改這個數組表示你消費
     * 了多少距離。假設用戶滑動了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, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed,type);
    }



    /**
     * 進行嵌套滾動時被調用
     * @param coordinatorLayout
     * @param child
     * @param target
     * @param dxConsumed target 已經消費的x方向的距離
     * @param dyConsumed target 已經消費的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, int type) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,type);
    }

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

    /**
     * onStartNestedScroll返回true纔會觸發這個方法,接受滾動處理後回調,可以在這個
     * 方法裏做一些準備工作,如一些狀態的重置等。
     * @param coordinatorLayout
     * @param child
     * @param directTargetChild
     * @param target
     * @param nestedScrollAxes
     */
    @Override
    public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild,
                                       View target, int nestedScrollAxes,int type) {
        super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes,type);
    }

    /**
     * 用戶鬆開手指並且會發生慣性動作之前調用,參數提供了速度信息,可以根據這些速度信息
     * 決定最終狀態,比如滾動Header,是讓Header處於展開狀態還是摺疊狀態。返回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 進行重新佈局
    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
        return super.onLayoutChild(parent, child, layoutDirection);
    }
    
}
<?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=".view.BehaviorActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:elevation="0dp">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="#00ffffff"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="@mipmap/meizhi"
                android:fitsSystemWindows="true"
                android:scaleType="fitXY"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/scollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="111"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="222"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="333"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="444"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="555"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="666"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:text="777"/>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>


    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#ff0000"
        android:gravity="center"
        android:text="Hello World"
        android:textColor="#ffffff"
        android:textSize="18sp"
        app:layout_behavior=".behavior.BehaviorTest"/>

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

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章