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>

在这里插入图片描述

发布了383 篇原创文章 · 获赞 54 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/hongxue8888/article/details/104017780
今日推荐