摘要:好了,关于的使用我就先介绍到这了图片上传中如果觉得这篇文章对你有帮助,点个赞鼓励一下吧
前言
看过前两篇文章的同学
sidhu眼中的CoordinatorLayout.Behavior(一)
sidhu眼中的CoordinatorLayout.Behavior(二)
应该知道今天要讲的内容了——Behavior的布局依赖
其实这个内容挺少的,我都想直接贴代码然大家自己体会了……额,开玩笑的,不过内容真的少,我也不浪费大家时间了,疑问我不提了,直入主题
(有木有直入主题,哈哈~)
我将上次的例子做了下修改
xml:
相比于之前的布局我们可以看到,就多了一个小方块在布局里面,至于我想实现的效果可以看下面效果图
让小方块可以随着上面的head做同步的位移
就如我上篇所说的,使用原理还是实现NestedScrollingChild接口,废话不多说,上代码(没错,我就是这样的人,一言不合就上代码)
package com.mintmedical.mybehaviordemo; import android.animation.ValueAnimator; import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.support.v4.view.NestedScrollingChild; import android.support.v4.view.NestedScrollingChildHelper; import android.util.AttributeSet; import android.view.View; /** * Created by SidHu on 2016/8/17. */ public class HideHeadBehavior extends CoordinatorLayout.Behavior implements NestedScrollingChild { private boolean isHeadHide = false; private boolean isAnimating = false; private final int SCROOL_VALUE = 50; private int childHeight; private final int animationDuration = 500; private NestedScrollingChildHelper childHelper; public HideHeadBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @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(); } if (childHelper == null) { childHelper = new NestedScrollingChildHelper(child); } return true; } else { return false; } } @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); } } 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() { @Override public 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() { @Override public 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(); } @Override public void setNestedScrollingEnabled(boolean enabled) { childHelper.setNestedScrollingEnabled(enabled); } @Override public boolean isNestedScrollingEnabled() { return childHelper.isNestedScrollingEnabled(); } @Override public boolean startNestedScroll(int axes) { return childHelper.startNestedScroll(axes); } @Override public void stopNestedScroll() { childHelper.stopNestedScroll(); } @Override public boolean hasNestedScrollingParent() { return childHelper.hasNestedScrollingParent(); } @Override public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { return childHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow); } @Override public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { return childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow); } @Override public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { return childHelper.dispatchNestedFling(velocityX, velocityY, consumed); } @Override public boolean dispatchNestedPreFling(float velocityX, float velocityY) { return childHelper.dispatchNestedPreFling(velocityX, velocityY); } }
我将head实现了NestedScrollingChild接口,然后就没有做其他事情了。(这也说明了,想让控件通知CoordinatorLayout自己的状态其实只要实现了NestedScrollingChild接口就够了,假如你不需要关心滑动手势,就像小方块只关心head的位移一样,那你startNestedScroll之类的这样方法都不用要了)
那我们看一下小方块的Behavior
package com.mintmedical.mybehaviordemo; import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.util.AttributeSet; import android.view.View; /** * Created by SidHu on 2016/8/18. */ public class MoveWithHeadBehavior extends CoordinatorLayout.Behavior{ private int lastBottom = -1; public MoveWithHeadBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { return dependency.getId() == R.id.rel_head; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { if (lastBottom == -1) { lastBottom = dependency.getBottom(); } if (dependency.getBottom() != lastBottom) { int d = dependency.getBottom()-lastBottom; lastBottom = dependency.getBottom(); child.offsetTopAndBottom(d); } return super.onDependentViewChanged(parent, child, dependency); } }
代码也是非~非~非~非常简单,布局依赖最主要的关系这两个方法,一个是判断是不是自己关心的target View(跟滑动的时候简直一毛一样),一个是被关心的target View变化以后的回调,代码我就不解释啦,也是很简单(大家有什么问题可以在评论里面问我啊)。
好了,关于Behavior的使用我就先介绍到这了
![图片上传中...]
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/13088.html
摘要:仔细思考发现,实现嵌套滑动的关键,其实就是将自身的滑动事件告诉其他控件。接收到滑动数据后,假如动画结束,对滑动的值进行一个阈值和方向的判断,然后调用对应动画。 前言 在上一节sidhu眼中的CoordinatorLayout.Behavior(一)中,我们讲解了如何以通过Behavior来重写某个控件的触摸事件可是我们只讲了如何将触摸事件抛出来,那怎么对这些数据进行处理呢?这就是我们今...
摘要:最近几天,我整理出了一些思路,跟大家分享下。看到这里,我们就有了一个大致思路流程了强行带一波节奏,哈哈原来,只是将传过来的数据进行了一次封装,分发给了自己子布局里面所有含有的控件,交由它们进行处理。 前言 Behavior是Android Design中推荐的布局概念,网上找了很多关于Behavior的资料,很多都是直接翻译的文档或者浅尝辄止,很多问题都没有讲明白,例如具体怎么自定义B...
摘要:判断依赖对象当收到某个的变化或者嵌套滑动事件时,就会尝试把事件下发给,绑定了该的就会对事件做出响应。另外的两种布局事件触摸事件就没有这一步了。变化事件这个变化是指的位置尺寸发生了变化。由主动发出滑动事件传递给,做出响应。 前言 许多文章都是将CoordinatorLayout、AppbarLayout、CollapsingToolbarLayout、Toolbar等放在一起介绍,容易误...
摘要:在发布后,我们获得了一个新的用来实现的提供了一系列符合设计标准的控件。这个是在进行的过程中,利用对象对子进行大小测量的一个方法。这和传统的不同,子从此知道了彼此之间的存在,一个子的变化可以通知到另一个子。使用对象进行通信。 在Android M Preview发布后,我们获得了一个新的support library —— Android Design Support Library 用...
摘要:滑动抖动问题分析向上滚动无法被外部中断和子的联动时通过实现的,使用的继承了。当产生的向上的没有结束时,又送来向下的,抖动就产生了。反射获取私有的属性,考虑以后变量名修改的问题及一下版本可能是及以上版本然后在拦截事件里处理逻辑。 目录介绍 01.CoordinatorLayout滑动抖动问题描述 02.滑动抖动问题分析 03.自定义AppBarLayout.Behavior说明 04....
阅读 2045·2021-11-19 09:40
阅读 2425·2021-09-30 09:48
阅读 2460·2019-08-30 14:10
阅读 2612·2019-08-29 11:22
阅读 1728·2019-08-26 13:51
阅读 2141·2019-08-26 12:02
阅读 2224·2019-08-23 16:06
阅读 3411·2019-08-23 14:06