介绍

Interaction behavior plugin for child views of {@link CoordinatorLayout}.

A Behavior implements one or more interactions that a user can take on a child view.
These interactions may include drags, swipes, flings, or any other gestures.


@param < V > The View type that this Behavior operates on

交互行为主要用于CoordinatorLayout的子View。一个Behavior可以在一个字View上实现一个或者多个交互内容。这些交互可能包括拖拽,滑动,滚动或者是其他手势。
参数V代表这个Behavior可以操作的视图类型

类结构

<Android 基础(二十)> CoordinatorLayout Behavior

初步实战

关注两个方面:
1、实现child view 监听另外一个child view的状态变化,例如大小、位置、显示状态等
关注layoutDependsOn和onDependentViewChanged方法。

2、实现child view监听CoordinatorLayout内NestedScrollingChild的接口实现类的滑动状态
关注onStartNestedScroll和onNestedPreScroll方法。如上一篇博文中提到的NestedScrollView,而不能使用普通的ScrollView

第一种情况,监听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:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="mraz.com.coordinatorlayoutdemo.ScrollingActivity">

    <TextView
        android:id="@+id/depentent"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="top|left"
        android:background="#73ff00"
        android:gravity="center"
        android:text="depentent"
        android:textColor="@android:color/black" />

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="top|right"
        android:background="#ffee00"
        android:gravity="center"
        android:text="auto"
        android:textColor="@android:color/holo_red_dark"
        app:layout_behavior="mraz.com.coordinatorlayoutdemo.FollowingBehavior" />
</android.support.design.widget.CoordinatorLayout>


Behavior

package mraz.com.coordinatorlayoutdemo;

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Mraz on 2016/8/15.
 */
public class FollowingBehavior extends CoordinatorLayout.Behavior<View> {
    public FollowingBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return (dependency.getId() == R.id.depentent);//依赖左边的View 
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        int offsetX = dependency.getTop() - child.getTop();//拿到左边View和右边view的顶部差距
        ViewCompat.offsetTopAndBottom(child, offsetX);//移动
        return true;
    }
}


实际效果
<Android 基础(二十)> CoordinatorLayout Behavior


第二种情况,监听滚动状态

CoordinatorLayout实现NestedScrollingParent接口,

NestedScrollView实现NestedScrollingParent, NestedScrollingChild, ScrollingView接口

public class NestedScrollView extends FrameLayout implements NestedScrollingParent,
        NestedScrollingChild, ScrollingView

说白了就是一个加强的ScrollView,但是实现的这几个接口是怎么回事呢?一个个的看下

NestedScrollingParent

<Android 基础(二十)> CoordinatorLayout Behavior

Interface Meaning
onStartNestedScroll child执行startNestedScroll方法的时候会调用,返回true代表代表要和child联动
onNestedScrollAccepted onStartNestedScroll执行完成并返回true之后执行,用于做联动前的准备
onStopNestedScroll nested scroll结束后执行
onNestedScroll nested scroll进行中时执行,传递的参数是消耗了和没有消耗的滚动距离
onNestedPreScroll neseted scroll进行并且target没有消耗滚动时执行,nested scrolling执行dispatchNestedPreScroll后执行该方法
onNestedFling 请求一个滚动结束后的fling
onNestedPreFling target view没有消耗flinger之前执行
getNestedScrollAxes 返回NestedScrollingParent的滚动轴


NestedScrollingChild

<Android 基础(二十)> CoordinatorLayout Behavior

Interface Meaning
setNestedScrollingEnabled 设置视图是否可以nested scrolling
isNestedScrollingEnabled 获取当前view是否可以nested scrolling
startNestedScroll 开始执行nested scroll,沿着给点的轴方向,返回true,代表找到了parent
stopNestedScroll 停止nested scroll
hasNestedScrollingParent 判断nested scrolling是否存在parent
dispatchNestedScroll 派发一个滚动给parent
dispatchNestedPreScroll 在没有消耗之前派发给parent,也就是parent有可能会在child之前消耗
dispatchNestedFling 派发fling给parent
dispatchNestedPreFling 消耗之前派发给parent


ScrollingView

<Android 基础(二十)> CoordinatorLayout Behavior

Interface Meaning
computeHorizontalScrollRange 计算横向滚动的范围
computeHorizontalScrollOffset 计算横向偏移量
computeHorizontalScrollExtent 计算横向额外距离
computeVerticalScrollRange 滚动视图的可滚动范围是所有子元素的高度
computeVerticalScrollOffset 计算垂直方向滚动条的滑块的偏移。此值用来计算滚动条轨迹的滑块的位置
computeVerticalScrollExtent 计算纵向额外距离

关于NestedScrollingParent和NestedScrollingChild,存在两个Helper类

<Android 基础(二十)> CoordinatorLayout Behavior

<Android 基础(二十)> CoordinatorLayout Behavior
基本上方法和上面的比较类似,不赘述
看实例:
布局文件

<?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:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:scrollbars="vertical"
    tools:context="mraz.com.coordinatorlayoutdemo.ScrollingActivity">

    <android.support.v4.widget.NestedScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

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

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#73ff00"
                android:gravity="center"
                android:text="depentent"
                android:textColor="@android:color/black" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        app:layout_behavior="mraz.com.coordinatorlayoutdemo.MyScrollingBehavior">

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

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ff00aa"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        app:layout_behavior="mraz.com.coordinatorlayoutdemo.MyScrollingBehavior">

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

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />

            <TextView
                android:layout_width="100dp"
                android:layout_height="200dp"
                android:layout_gravity="top|left"
                android:background="#ffe600"
                android:gravity="center"
                android:text="right"
                android:textColor="@android:color/black" />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

3条杠杠~

Behavior

package mraz.com.coordinatorlayoutdemo;

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.View;

public class MyScrollingBehavior extends CoordinatorLayout.Behavior {
    public MyScrollingBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;//只对垂直滚动感兴趣
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        int leftScrolled = target.getScrollY();//获取左侧滚动距离
        child.setScrollY(leftScrolled);//设置联动
    }

    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
        ((NestedScrollView) child).fling((int) velocityY);//松手后速度传递下去
        return true;
    }
}

实际效果
<Android 基础(二十)> CoordinatorLayout Behavior


备注

参考博客:
http://blog.csdn.net/qibin0506/article/details/50290421

相关文章: