属性动画可直接改变View的属性值,属性动画几乎可以对任意对象执行动画,而不局限在View对象执行动画。
基本属性
动画持续时间:默认值是300ms,通过android:duration指定
动画插值方式:android:interpolator
动画重复次数:动画重复播放次数,android:repeatCount
动画重复模式:在一次动画播放结束后,重复下次动画时,是从开始帧再次播放到结束帧,还是从结束帧反方向播放到开始帧。android:repeatMode
帧刷新频率:指定间隔多长时间播放一帧,默认值是10毫秒
动画集合
Eavluator
是用来控制属性动画如何计算属性值的。
它的接口是TypeEvalutor,其中定义了evaluate方法,供不同的子类实现。
public interface TypeEvaluator {
public T evaluate(float fraction, T startValue, T endValue);
}
**输入初始值和结束值及一个进度比,计算每个进度对应的值。
常见的实现类有
ArgbEvaluator,IntEvaluator,FloatEvaluator
ValueAnimator
属性动画最重要的一个类,继承自Animator,它定义了属性动画大部分的核心功能,包括计算各帧的属性值,处理更新时间,按照属性值的类型控制计算规则等。
一个完整的属性动画由两部分组成:
1.计算动画各帧的相关属性值。
2.将这些属性值设置给指定对象。
ValueAnimator为开发者完成了第一部分的功能,第二部分功能由开发者自行设置。
ValueAnimator的构造函数是空实现,一般由使用静态工厂方法来进行实例化。
public static ValueAnimator ofInt(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}
public static ValueAnimator ofArgb(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
anim.setEvaluator(ArgbEvaluator.getInstance());
return anim;
}
public static ValueAnimator ofFloat(float... values) {
ValueAnimator anim = new ValueAnimator();
anim.setFloatValues(values);
return anim;
}
public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) {
ValueAnimator anim = new ValueAnimator();
anim.setValues(values);
return anim;
}
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
ValueAnimator anim = new ValueAnimator();
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}
获取实例,设置动画持续时间,差值方式,重复次数等属性值,启动动画。为ValueAnimator 注册addUpdateListener监听器,并在这个方法中计算出来的属性设置给指定对象。
int statusBarColor = this.getWindow().getStatusBarColor();
ValueAnimator valueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), statusBarColor, color);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Test.this.getWindow().setStatusBarColor((Integer) animation.getAnimatedValue());
}
});
valueAnimator.setDuration(300).setStartDelay(0);
valueAnimator.start();
ValueAnimator改变高度案例
隐藏显示—
1通过更改height逐渐的变为0
2更改整个view的paddingyop—改成父值
为了整体控制动画—在外面再包一层布局
开始默认隐藏三个布局
//一开始应该让下面的三个布局隐藏,将其height设置为0--通过params
//为了获取最初的高度--设置一个布局监听器--局对可以取到宽高
llSafeAnim.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
llSafeAnim.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//记录最初的高度--一遍之后变回来
height = llSafeAnim.getHeight();
//将当前的高度设置为0--隐藏---这里使用.getLayoutParams因为在布局里面写
//线性布局是继承自viewgroup
ViewGroup.LayoutParams params = llSafeAnim.getLayoutParams();
params.height = 0;
llSafeAnim.setLayoutParams(params);
}
});
点击切换动画
int height;//最初的高度
//定义变量boolean--完成切换--默认为不打开
boolean isOpen = false;
//设置整个模块条目的点击事件
@OnClick(R.id.safe_module)
public void onViewClicked() {
//ValueAnimator控制值在指定范围内改变的动画对象, 注意:它只是负责让值进行改变,
//本身不会有任何的动画效果
ValueAnimator animator = null;
if (isOpen) {
//ValueAnimator使用--需要关闭
animator = ValueAnimator.ofInt(height, 0);
} else {
//ValueAnimator使用--需要打开
animator = ValueAnimator.ofInt(0, height);
}
//设置时间
animator.setDuration(600).start();
//置为反值
isOpen = !isOpen;
}
监听值的变化过程—将值设置给height实现动画—执行之前进行监听
//监听值的变化过程
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获取动画的值--默认是object类型--强转
int animatedValue = (int) animation.getAnimatedValue();
//我们只需要将值设置给height
ViewGroup.LayoutParams params = llSafeAnim.getLayoutParams();
params.height = animatedValue;
llSafeAnim.setLayoutParams(params);
}
});
添加监听动画结束语开始
//监听动画
animator.addListener(new MyAnimatorListener());
//设置时间
animator.setDuration(600).start();
//置为反值
isOpen = !isOpen;
class MyAnimatorListener extends AnimatorListenerAdapter {
//当动画结束
@Override
public void onAnimationEnd(Animator animation) {
isAnimRunning = false;
}
///当动画开始
@Override
public void onAnimationStart(Animator animation) {
isAnimRunning = true;
}
}
ObjectAnimator
ObjectAnimator是ValueAnimator 的子类,封装实现了属性值设置给指定对象的功能.
只有在ObjectAnimator实现不了的场景下才考虑使用ValueAnimator 。
ObjectAnimator最大的不同是在构造实例中需要指定作用的具体对象和对象的属性名,而且一般不需要注册addUpdateListener监听器。
传统animator--Objectanimator.ofXXX
透明效果-alpha
//获取ObjectAnimator对象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "alpha",
1.0f, 0.5f, 0.0f, 0.2f, 0.7f, 1.0f);
// 参数1:target 目标:产生的动画效果 谁来执行
// 参数2:属性名字 字符串类型--针对(参数1)控件来说 --alpha透明--可以通过
// 控件.set看一下都有哪些方法--也就是有什么参数
// 参数3:可变参数--数组
//设置动画执行时间
objectAnimator.setDuration(2000);
//开始执行动画
objectAnimator.start();
旋转效果
//获取ObjectAnimator对象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "rotationX", 0, 90, 180, 360);
// 参数1:target 目标:产生的动画效果 谁来执行
// 参数2:属性名字 字符串类型--针对(参数1)控件来说 --rotationX按照x轴移旋转--可以通过
// 控件.set看一下都有哪些方法--也就是有什么参数
// 参数3:可变参数--数组
//设置动画执行时间
objectAnimator.setDuration(2000);
//开始执行动画
objectAnimator.start();
缩放动画
//获取ObjectAnimator对象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "scaleX",
1.0f, 2.0f, 3.0f);
// 参数1:target 目标:产生的动画效果 谁来执行
// 参数2:属性名字 字符串类型--针对(参数1)控件来说 --scaleX按照x轴缩放--可以通过
// 控件.set看一下都有哪些方法--也就是有什么参数
// 参数3:可变参数--数组
//设置动画执行时间
objectAnimator.setDuration(2000);
//开始执行动画
objectAnimator.start();
位移动画
//获取ObjectAnimator对象
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv,
"translationX", 20, 30, 40, 100, -150);
// 参数1:target 目标:产生的动画效果 谁来执行
// 参数2:属性名字 字符串类型--针对(参数1)控件来说 --translationX按照x轴移动--可以通过
// 控件.set看一下都有哪些方法--也就是有什么参数
// 参数3:可变参数--数组
//设置动画执行时间
objectAnimator.setDuration(2000);
//开始执行动画
objectAnimator.start();
动画合集
AnimatorSet 是Animator的子类,用来组合多个animator。
AnimatorSet set = new AnimatorSet();
ObjectAnimator aa = ObjectAnimator.ofFloat(iv, "alpha", 1.0f, 0.5f,
0.0f, 0.2f, 0.7f, 1.0f);
ObjectAnimator ra = ObjectAnimator.ofFloat(iv, "rotationX", 0, 90, 180,
360);
ObjectAnimator sa = ObjectAnimator.ofFloat(iv, "scaleX", 1.0f, 2.0f,
3.0f);
ObjectAnimator ta = ObjectAnimator.ofFloat(iv, "translationX", 20, 30,
40, 100, -150);
//四个动画一起执行
// set.playTogether(aa,ra,sa,ta);
//四个动画顺序执行
set.playSequentially(aa, ra, sa, ta);
//设置iv来执行动画
set.setTarget(iv);
//设置执行时间
set.setDuration(2000);
//开始执行
set.start();
标准写法
//属性动画的标准写法:
//ViewCompat.animate(tv1).translationZBy(100).setDuration(3000).start();
//带by每次都会执行--不带by只执行一次
ViewCompat.animate(tv1)
.translationZBy(100)
//.rotationBy(720)
//旋转
.rotationYBy(720)//绕着y轴旋转
//缩放
.scaleXBy(0.3f)
.scaleYBy(0.3f)//每次放大0.3
//移动
.translationYBy(20)
//.alphaBy()透明
//灵动的感觉
//OvershootInterpolator超过后再回来
//.setInterpolator(new OvershootInterpolator())
//BounceInterpolator--弹簧的感觉
.setInterpolator(new BounceInterpolator())
.setDuration(3000).start();
http://www.jianshu.com/p/2412d00a0ce4