前言

在上一节sidhu眼中的CoordinatorLayout.Behavior(一)中,我们讲解了如何以通过Behavior来重写某个控件的触摸事件
可是我们只讲了如何将触摸事件抛出来,那怎么对这些数据进行处理呢?这就是我们今天要讲的内容了,Behavior的嵌套滑动机制
首先我们来理解一下什么是嵌套滑动,了解Android Design的大家想必已经非常熟悉这种交互了

在一个控件滑动的同时,动态调整自身或其他控件的宽高或位置来达到更好的交互。
其实说白了,这个就是NestedScrollingParent和NestedScrollingChild的实际运用(不清楚的同学可以看这篇文章,Android 嵌套滑动机制(NestedScrolling))。仔细思考发现,实现嵌套滑动的关键,其实就是将自身的滑动事件告诉其他控件。现在大家知道我写第一篇文章的那个Behavior的用途了吧,哈哈、

那我们就开始讲解今天的内容,同样,在文章的开始,我们先提出几个疑问:

  1. A发出消息,E也发出消息,怎样判断哪个是我们想要处理的滑动事件?

  2. A使B变化的同时,A能否也能一起变化?

  3. A使B发生改变的同时,B是否能发出消息,使C根据自己变化?

A发出消息,E也发出消息,怎样判断哪个是我们想要处理的滑动事件?

我们再来看一下之前提过的Behavior的处理逻辑图

当收到触摸事件后,CoordinatorLayout通知了所有的Behavior,换句话讲,就是Behavior会收到自己不需要处理的滑动事件。
我们来重写一下Behavior的onStartNestedScroll方法,会发现里面有个叫做target的View参数传进来,而这个target就是发出这个滑动事件的View。其对应的,就是当初写NestedScrollingChildHelper时,传入的那个View。而onStartNestedScroll方法是在target调用了startNestedScroll的时候才被调用的,也就是滑动事件发出的起始时间点,所以此时用这个taget来判断是否是我们所关心的那个view发出的最适合不过了。至于是用id(getId)还是类型(instanceof)来判断就看你自己喜欢了、、
在onStartNestedScroll这个方法里,return true则对后续的操作进行处理,return false则忽略掉,后续方法不会被调用。

A使B变化的同时,A能否也能一起变化?

这个答案当然也是肯定的啦,你连target对象都拿到了,还有什么不能做,哈哈、、
说的多不如实战练一下。那我们接着昨天的写,网上很多都是根据滑动位移移到对应距离的例子,那我们不妨写一个其他的例子:根据手势的上滑下滑来用动画效果隐显头部。
大致效果是这样的

蓝色部分用的是我们上一篇文章写的Behavior,而红色部分则用我们今天写的Behavior。

先看一下xml文件

<?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"><Viewandroid:id="@+id/rel_head"android:layout_width="match_parent"android:layout_height="200dp"android:background="@color/colorAccent"app:layout_behavior=".HideHeadBehavior" /><Viewandroid:id="@+id/rel_body"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginTop="200dp"android:background="@color/colorPrimaryDark"app:layout_behavior=".TouchBehavior" /></android.support.design.widget.CoordinatorLayout>

布局很简单,上面有个200dp高的红色部分,红色下面是蓝色部分

Activity更简单,因为它什么都不用做、、

public class TouchTestActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_touch_text);}}

那重点是我们的Behavior了

package com.mintmedical.mybehaviordemo;import android.animation.ValueAnimator;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;/*** Created by SidHu on 2016/8/17.*/
public class HideHeadBehavior extends CoordinatorLayout.Behavior {private boolean isHeadHide = false;private boolean isAnimating = false;private final int SCROOL_VALUE = 50;private int childHeight;private final int animationDuration = 500;public HideHeadBehavior(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {if (target.getId() == R.id.rel_body) {if (childHeight == 0) {childHeight = child.getHeight();}return true;} else {return false;}}@Overridepublic void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);if (isAnimating) {return;}if (dy > SCROOL_VALUE && !isHeadHide) {hide(child, target);} else if (dy < -SCROOL_VALUE && isHeadHide) {show(child, target);}}public void hide(final View child, final View target) {isHeadHide = true;ValueAnimator valueAnimator = new ValueAnimator();valueAnimator.setIntValues(0, childHeight);valueAnimator.setDuration(animationDuration);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {if (child.getBottom() > 0) {int value = (int) animation.getAnimatedValue();isAnimating = value != childHeight;child.layout(child.getLeft(), -value, child.getRight(), -value + childHeight);target.layout(target.getLeft(), -value + childHeight, target.getRight(), target.getBottom());}}});valueAnimator.start();}public void show(final View child, final View target) {isHeadHide = false;ValueAnimator valueAnimator = new ValueAnimator();valueAnimator.setIntValues(0, childHeight);valueAnimator.setDuration(animationDuration);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {if (child.getBottom() < childHeight) {int value = (int) animation.getAnimatedValue();isAnimating = value != childHeight;child.layout(child.getLeft(), value - childHeight, child.getRight(), value);target.layout(target.getLeft(), value, target.getRight(), target.getBottom());}}});valueAnimator.start();}}

代码简直非~~非~非常简单,对嘛,写demo就是要简单,有时候看别人写的demo,无关业务一大堆,代码老长,看了半天才找到那句对我有用的代码。
这个类里,排除两个值动画,只有两个方法

@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {if (target.getId() == R.id.rel_body) {if (childHeight == 0) {childHeight = child.getHeight();}return true;} else {return false;}
}

判断是否为我们关心的target对象,是返回true,否返回false,顺便获取了下child(也就是红色部分)的高度。

@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);if (isAnimating) {return;}if (dy > SCROOL_VALUE && !isHeadHide) {hide(child, target);} else if (dy < -SCROOL_VALUE && isHeadHide) {show(child, target);}
}

接收到滑动数据后,假如动画结束,对滑动的值进行一个阈值和方向的判断,然后调用对应动画。
而在值动画里面,我们就仅仅不停改变Head和Body的Layout位置,实现动画效果、
整个类就解释完了!快去试试在手机上的运行效果吧、

A使B发生改变的同时,B是否能发出消息,使C根据自己变化?

就得嘛得!!!!
不是还有一个问题嘛、、、
这个问题的回答当然也是肯定的啦,其实聪明的你或许已经猜想到应该怎么实现了,没错,就是根据第一篇文章依葫芦画瓢嘛。哈哈,赶紧试一试吧、不过到时候我写的会有点稍微不一样,因为下一篇要讲的是:Behavior的布局依赖、、
sidhu眼中的CoordinatorLayout.Behavior(三)

如果觉得这篇文章对你有帮助,点个赞鼓励一下吧、、(●'◡'●)

sidhu眼中的CoordinatorLayout.Behavior(二)相关推荐

  1. sidhu眼中的CoordinatorLayout.Behavior(一)

    前言 Behavior是Android Design中推荐的布局概念,网上找了很多关于Behavior的资料,很多都是直接翻译的文档或者浅尝辄止,很多问题都没有讲明白,例如具体怎么自定义Behavio ...

  2. 反编译简书app和小红书app滑动效果sticky粘性头布局的实现CoordinatorLayout+behavior

    反编译简书app和小红书app滑动效果sticky粘性头布局的实现CoordinatorLayout+behavior 小红书效果: 简书效果: demo效果图: github地址:https://g ...

  3. android 模拟滑动app,反编译简书app和小红书app滑动效果sticky粘性头布局的实现CoordinatorLayout+behavior...

    反编译简书app和小红书app滑动效果sticky粘性头布局的实现CoordinatorLayout+behavior 小红书效果: xiaohongshuu.gif 简书效果: jianshug.g ...

  4. android 5 .0下拉回弹,自定义CoordinatorLayout.Behavior 实现下拉回弹

    先看效果 123.gif package com.tospur.exmind.testrecycerviewwithtopandbottomrefresh.refresh; import androi ...

  5. 老曹眼中的研发管理二三事

    这是在gitchat上的第一次分享,中生代联手gitchat在做研发管理的专题活动,作为先锋,抛砖引玉. 关于管理,必然会谈到业界先贤德鲁克先生对管理的定义. 管理就是界定企业的使命,并激励和组织人力 ...

  6. Android:自定义CoordinatorLayout.behavior 简单的仿UC首页

    CoordinatorLayout顾名思义协调布局,是用来协调该布局下的子控件,最简单地使用就是头部伸缩和折叠了,配合着TabLayout,只需要设置一下AppBarLayout子控件的layout_ ...

  7. CoordinatorLayout+Behavior讲解

    文章开始前奉送上代码,方便大家对照学习 1.前言 CoordinatorLayout是在Google I/O 15上,谷歌发布了一个新的 support library中的控件,它是support l ...

  8. 源码看CoordinatorLayout.Behavior原理

    在上一篇博客CoordinatorLayout高级用法-自定义Behavior中,我们介绍了如何去自定义一个CoordinatorLayout的Behavior,通过文章也可以看出Behavior在C ...

  9. Error: Program type already present: android.support.design.widget.CoordinatorLayout$Behavior 预览器异常

    添加依赖和自己的版本不符合,根据自己的最低版本进行导入适合的包,比如我这里是26.28就应该导入26-28版本的android包

最新文章

  1. JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性
  2. 源码分析-GLSurfaceView的内部实现
  3. 日志切割清理工具 Log-Cutter
  4. java反射field和method的顺序问题
  5. Inside ASP.NET 2.0 – Controls Model(转载)
  6. 这也太狠了吧!500套Java实用代码,不论工作学习都能用到!
  7. tab栏切换 动画的相关方法上 动画的相关方法下 隐藏动画案例 隐藏动画练习
  8. public ServiceException() { super(); } public ServiceException(String message, Throwable cause,
  9. Android与Js交互时,屏幕不适配问题
  10. 分布式块设备复制:客户端
  11. Silver Cow Party 图论 最短路问题
  12. unity太空射击源码_引擎入门 | 创建双杆射击游戏(入门 2)
  13. 如何才能写出“高质量”的代码?
  14. 给初学者的20个CSS实用建议
  15. 你安全吗网剧技术探讨-个人向
  16. 情人节送男生什么礼物好,情人节送礼清单
  17. 微信卡券开发错误自排查参考文档
  18. web前端压缩图片方法——加快页面加载速度
  19. 基于opencv的模式识别——水果类别识别与计数
  20. 记录下我磕磕碰碰的三个月找工作经历,offer拿到手软

热门文章

  1. asp.net 开发疑问?
  2. requests(二): json请求中固定键名顺序消除键和值之间的空格
  3. Formik官方应用案例解析( 五)React Native
  4. 为了新零售,A.O.史密斯做出一个令人吃惊的决定
  5. Linux多线程总结
  6. mac下Android studio配置gradle的路径
  7. 翻译连载 | JavaScript轻量级函数式编程-第7章: 闭包vs对象 |《你不知道的JS》姊妹篇...
  8. Google 已正式结束对 Eclipse Android 的支持
  9. 脚本自动配置ssh互信
  10. Improved Alpha-Tested Magnification for Vector Textures and Special Effects