1、简介
本篇博客记录的是开发中用的比较多的属性动画,还有和属性很类似的动画。
属性动画概念:属性动画的实现机制是通过对目标对象进行赋值并修改其属性来实现的;而补间动画只能针对view进行平移,旋转,缩放,渐变四种操作,且只是从视觉修改其绘制位置,其实际点击事件并不会生效。
public final class ObjectAnimator extends ValueAnimator
属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的
属性动画有2个不得不提的概念:Interpolator(插值器) 和 Evaluator
public class MyLinearInerpolator implements Interpolator {
// 返回值是进度值 ofInt(那么值就是从0-1中返回的一个值)
@Override
public float getInterpolation(float input) {
return input;
}
}
Evaluator:通过进度值依据规则计算具体的数值
2、分类
1. 旋转动画
private void propertyRotation(View view){
ObjectAnimator.ofFloat(mIv,View.ROTATION,0,180f).setDuration(2000).start(); //按钮1
ObjectAnimator.ofFloat(mIv,View.ROTATION,180f,0).setDuration(2000).start(); //按钮2
ObjectAnimator.ofFloat(mIv,View.ROTATION,-180f,0).setDuration(2000).start();//按钮3
}
综述:
1.可以使用View.ROTATION.getName()来获得旋转字符串值
2. 0-180f 顺时针旋转 Android 坐标系与数学坐标系y轴相反
180f-0f 逆时针旋转
-180-0 顺时针旋转
对于Android坐标系而言,-180 和 180是同一坐标点
2. 使用动画自带的数值器,在自定义VIew中的使用
如下为2个在日常开发中用到的动画插值,渐进的改变状态
mValueAnimator = ValueAnimator.ofFloat(start, end);
mValueAnimator.setDuration(animTime);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
mPercent = (float) valueAnimator.getAnimatedValue();
mValue = mPercent * mMaxValue;
mCurrentValue = mValue;
invalidate();
}
});
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
// 停止完了
mIsStopingOn = false;
}
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
// 正在停止
mIsStopingOn = true;
}
});
mValueAnimator.start();
private ValueAnimator showCollapsedAnimation(final View mTargetView, final int mStartHeight, final int mEndHeight){
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
final int newHeight = (int)((mEndHeight - mStartHeight) * (float)valueAnimator.getAnimatedValue() + mStartHeight);
mTv.setMaxHeight(newHeight - mMarginBetweenTxtAndBottom);
if (Float.compare(mAnimAlphaStart, 1.0f) != 0) {
applyAlphaAnimation(mTv, mAnimAlphaStart + (float)valueAnimator.getAnimatedValue() * (1.0f - mAnimAlphaStart));
}
mTargetView.getLayoutParams().height = newHeight;
// 这个很重要 和invidate一样的牛逼 一个是 measure layout 一个是 draw
mTargetView.requestLayout();
}
});
valueAnimator.setDuration(mAnimationDuration);
return valueAnimator;
}
3.ViewPropertyAnimator
是不需要知道起始点,也不需要过程,它要的仅仅是结果,而且这个结果是一个 绝对结果
//源码
public ViewPropertyAnimator animate() {
if (mAnimator == null) {
mAnimator = new ViewPropertyAnimator(this);
}
return mAnimator;
}
// 示例代码
mLlLoginPull.animate()
.translationYBy(height * progress)
.translationY(0)
.setDuration(time)
.start();
那么很明显了,translationY 这个API,它是相对于控件初始原点(即控件左上角),位移到Y轴250处,这个坐标点是一个绝对的,因为控件初始原点是绝对的。而 translationYBy 不同,它是以控件当前位置的原点作比较,随意会一直位移下去。最后,ViewPropertyAnimator 这个动画是没有setRepeat的方法,它的用法决定了这一点。