package com.view.behavior; import android.animation.Animator; import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v4.view.ViewCompat; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.util.AttributeSet; import android.view.View; import android.view.ViewPropertyAnimator; import android.view.animation.Interpolator; import java.util.List; /** * Created by baixiaokang on 16/12/15. */ public class MyCommentBehavior extends CoordinatorLayout.Behavior<View> { private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); private float viewY;//控件距离coordinatorLayout底部距离 private boolean isAnimate;//动画是否在进行 public MyCommentBehavior(Context context, AttributeSet attrs) { super(context, attrs); } //确定所提供的子视图是否有另一个特定的同级视图作为布局从属。 @Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { //这个方法是说明这个子控件是依赖Snackbar.SnackbarLayout的 return dependency instanceof Snackbar.SnackbarLayout; } private float getFabTranslationYForSnackbar(CoordinatorLayout parent, View fab) { float minOffset = 0; final List<View> dependencies = parent.getDependencies(fab); for (int i = 0, z = dependencies.size(); i < z; i++) { final View view = dependencies.get(i); if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) { minOffset = Math.min(minOffset, ViewCompat.getTranslationY(view) - view.getHeight()); } } return minOffset; } float mFabTranslationY = 0; //用于响应从属布局的变化 @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View snackbar) { if (child.getVisibility() != View.VISIBLE) { return false; } final float targetTransY = getFabTranslationYForSnackbar(parent, child); if (mFabTranslationY == targetTransY) { // We're already at (or currently animating to) the target value, return... return false; } mFabTranslationY = targetTransY; final float currentTransY = ViewCompat.getTranslationY(child); final float dy = currentTransY - targetTransY; if (Math.abs(dy) > (child.getHeight() * 0.667f)) { // If the FAB will be travelling by more than 2/3 of it's height, let's animate // it instead ViewCompat.animate(child) .translationY(targetTransY) .scaleX(1f) .scaleY(1f) .alpha(1f) .setInterpolator(new FastOutSlowInInterpolator()) .setListener(null); } else { // Make sure that any current animation is cancelled ViewCompat.animate(child).cancel(); // Now update the translation Y ViewCompat.setTranslationY(child, targetTransY); } return true; } private boolean isHided = false; //在嵌套滑动开始前回调 @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) { if (!isHided) { isHided = true; ViewCompat.setTranslationY(child, child.getHeight()); } if (child.getVisibility() == View.VISIBLE && viewY == 0) { //获取控件距离父布局(coordinatorLayout)底部距离 viewY = coordinatorLayout.getHeight() - child.getY(); } return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;//判断是否竖直滚动 } //在嵌套滑动进行时,对象消费滚动距离前回调 @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) { //dy大于0是向上滚动 小于0是向下滚动 if (dy >= 10 && !isAnimate && child.getVisibility() == View.GONE) { show(child); } else if (dy < -10 && !isAnimate && child.getVisibility() == View.VISIBLE) { hide(child); } } //隐藏时的动画 private void hide(final View view) { ViewPropertyAnimator animator = view.animate().translationY(viewY).setInterpolator(INTERPOLATOR).setDuration(200); animator.setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { isAnimate = true; } @Override public void onAnimationEnd(Animator animator) { view.setVisibility(View.GONE); isAnimate = false; } @Override public void onAnimationCancel(Animator animator) { show(view); } @Override public void onAnimationRepeat(Animator animator) { } }); animator.start(); } //显示时的动画 private void show(final View view) { ViewPropertyAnimator animator = view.animate().translationY(0).setInterpolator(INTERPOLATOR).setDuration(200); animator.setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { view.setVisibility(View.VISIBLE); isAnimate = true; } @Override public void onAnimationEnd(Animator animator) { isAnimate = false; } @Override public void onAnimationCancel(Animator animator) { hide(view); } @Override public void onAnimationRepeat(Animator animator) { } }); animator.start(); } }