<Android 基础(二十)> CoordinatorLayout Behavior

介绍

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可以操作的视图类型

类结构

这里写图片描述

初步实战

关注两个方面:
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;
    }
}


实际效果
这里写图片描述


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

CoordinatorLayout实现NestedScrollingParent接口,

NestedScrollView实现NestedScrollingParent, NestedScrollingChild, ScrollingView接口

public class NestedScrollView extends FrameLayout implements NestedScrollingParent,
        NestedScrollingChild, ScrollingView

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

NestedScrollingParent

这里写图片描述

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

这里写图片描述

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

这里写图片描述

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

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

这里写图片描述

这里写图片描述
基本上方法和上面的比较类似,不赘述
看实例:
布局文件

<?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;
    }
}

实际效果
这里写图片描述


备注

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

posted on 2016-08-23 20:31  岚之山  阅读(392)  评论(0编辑  收藏  举报

导航