效果图:![](http://oenmdzxge.bkt.clouddn.com/%E8%8B%A5%E6%B0%B4GIF%E6%88%AA%E5%9B%BE_2016%E5%B9%B411%E6%9C%887%E6%97%A511%E7%82%B917%E5%88%860%E7%A7%92.gif)
![](http://oenmdzxge.bkt.clouddn.com/%E8%8B%A5%E6%B0%B4GIF%E6%88%AA%E5%9B%BE_2016%E5%B9%B411%E6%9C%887%E6%97%A511%E7%82%B921%E5%88%8629%E7%A7%92.gif)
一,定义基类:使用ValueAnimator定义动画执行的流程,具体的动画由子类实现
public abstract class BaseAnim { private ValueAnimator animator; protected View target;//执行动画的目标view public BaseAnim(View target,int startvalue,int endvalue) { this.target = target; animator = ValueAnimator.ofInt(startvalue, endvalue); //监听动画的执行流程,具体的动画由子类实现 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int animatedValue = (int) animator.getAnimatedValue(); doAnim(animatedValue); } }); } /** * 由子类实现的具体的动画 * @param animatedValue */ protected abstract void doAnim(int animatedValue) ; /** * 开启动画 * @param duration */ public void start(int duration){ animator.setDuration(duration).start(); } }
二,定义子类
1,PaddingTopAnim执行:
@Override protected void doAnim(int animatedValue) { target.setPadding(target.getPaddingLeft(), animatedValue, target.getPaddingRight(), target.getPaddingBottom()); }2,HeightAnim执行:
(与PaddingTopAnim不同的是,因为改变布局的高度可能使整个布局的高度大于屏幕的高度,故需要在布局上包裹一层ScrollView,通过接口暴露出动画变化的值传给ScrollView)
@Override protected void doAnim(int animatedValue) { ViewGroup.LayoutParams params = target.getLayoutParams(); params.height = animatedValue; target.setLayoutParams(params); //将动画变化的值通过接口暴露给外界(可用来让外界的scrollview移动) if (mOnHeightChangeListener != null) { mOnHeightChangeListener.OnHeightChange(animatedValue); } } private OnHeightChangeListener mOnHeightChangeListener; public void setmOnHeightChangeListener(OnHeightChangeListener mOnHeightChangeListener) { this.mOnHeightChangeListener = mOnHeightChangeListener; } private interface OnHeightChangeListener { void OnHeightChange(int animatedValue); }具体使用:略..(看demo吧嘻嘻)