介绍
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的状态
位置跟随
布局文件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{ 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,但是实现的这几个接口是怎么回事呢?一个个的看下
NestedScrollingParentInterface | 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类
基本上方法和上面的比较类似,不赘述 看实例: 布局文件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; }}
实际效果
备注
参考博客: