Property Animation Property Animation
Since Tween Animation (tween animation) can only realize four simple animations (alpha, scale, rotate, translate), it is difficult to meet the demand in order to realize more complex animations, and the tween animation only changes the drawing of the View object. The position of the View object itself is not changed, such as the transformation of the View shape, such as the scaling of the size, the change of the transparency, and the change of the position. , In fact, the body is still there motionless. What we often encounter in the development process is that the event is still in place after the translate. If you want to achieve both animation effects and real changes to the View itself, you need to use attribute animation, which is why attribute animation is introduced. It can achieve various effects more flexibly, not limited to those effects similar to tween animation.
ObjectAnimator:
A subclass of ValueAnimator that allows you to set a target object and object properties to animate. When this class calculates a new value for an animation, it updates its properties accordingly. Most of the time you'll want to use ObjectAnimator because it makes it easier to animate values to target objects.
Take the realization of a View transparent gradient effect as an example to illustrate
For java code implementation, ObjectAnimator provides the following methods: ofFloat() , ofInt() , ofObject() , ofArgb() , ofPropertyValuesHolder() These methods are used to set the element of animation effect, the attribute of effect, and the start of animation , end, and any attribute value in between.
//透明渐变效果
public void initXMLAnimAlpha() {
Animator anim = AnimatorInflater
.loadAnimator(context, R.animator.animator_alpha);
anim.setTarget(imageView);
anim.start();
}
public void initJavaAnimAlpha() {
ObjectAnimator alphaAnimation = ObjectAnimator
.ofFloat(imageView, "alpha", 0f, 1f);
alphaAnimation.setDuration(500);
alphaAnimation.setRepeatCount(0);
alphaAnimation.setRepeatMode(ValueAnimator.REVERSE);
alphaAnimation.setStartDelay(200);
alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
alphaAnimation.start();
}
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="alpha"
android:repeatCount="1"
android:repeatMode="reverse"
android:startOffset="200"
android:valueFrom="0.0"
android:valueTo="1.0"
android:valueType="floatType"/>
<!indicates which property value of the modified object, here is transparency
propertyNameindicates the animation execution time
--duration
repeatCount animation repetition count, the animation will execute the mode of this value + 1
repeatMode animation repetition, reverse is reverse, when it is executed for an even time,
the animation direction will be reversed. restart means re-execution, the direction remains the same.
startOffset , the interval between multiple executions of the animation, if it is executed only once, it
will pause for this period of time before execution, in milliseconds
valueFrom indicates the state value from which the animation starts
valueTo indicates the state value to which the animation ends
valueType Type evaluation, mainly used to set the value of the animation operation property
interpol
Zoom animation:
public void initXMLAnimScale() {
Animator anim = AnimatorInflater
.loadAnimator(context, R.animator.animator_scaleX);
anim.setTarget(imageView);
anim.start();
}
public void initJavaAnimScale() {
ObjectAnimator scaleXAnimator = ObjectAnimator
.ofFloat(imageView, "scaleX", 1f, 1.5f);
scaleXAnimator.setDuration(500);
scaleXAnimator.setRepeatCount(1);
scaleXAnimator.setRepeatMode(ValueAnimator.REVERSE);
scaleXAnimator.start();
}
R.animator.animator_scaleX
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="scaleX"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1.0"
android:valueTo="1.5"
android:valueType="floatType"/>
旋转动画:
public void initXMLAnimRotation() {
Animator anim = AnimatorInflater
.loadAnimator(context, R.animator.animator_rotation);
anim.setTarget(imageView);
anim.start();
}
public void initJavaAnimRotation() {
ObjectAnimator objectAnimator = ObjectAnimator
.ofFloat(imageView, "rotation", 0f, 360f);
objectAnimator.setDuration(500);
objectAnimator.setRepeatCount(1);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
objectAnimator.start();
}
R.animator.animator_rotation
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:interpolator=
"@android:anim/accelerate_decelerate_interpolator"
android:propertyName="rotation"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType"/>
平移动画:
public void initXMLAnimTranslationX() {
Animator anim = AnimatorInflater
.loadAnimator(context, R.animator.animator_translationX);
anim.setTarget(imageView);
anim.start();
}
public void initJavaAnimTranslationX() {
ObjectAnimator objectAnimator = ObjectAnimator
.ofFloat(imageView, "translationX", 0f, 100f);
objectAnimator.setDuration(500);
objectAnimator.setRepeatCount(1);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
objectAnimator.start();
}
R.animator.animator_translationX
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500"
android:propertyName="translationX"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="100"
android:valueType="floatType"/>
如何实现一个组合动画
方式一:使用AnimatorSet
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="500"
android:propertyName="scaleX"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1.0"
android:valueTo="1.5"
android:valueType="floatType"/>
<objectAnimator
android:duration="500"
android:propertyName="scaleY"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="1.0"
android:valueTo="1.5"
android:valueType="floatType"/>
</set>
//如何实现一个组合动画
public void initXMLAnimSet() {
Animator anim = AnimatorInflater
.loadAnimator(context, R.animator.animator_set);
anim.setTarget(imageView);
anim.start();
}
public void initJavaAnimSet() {
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator scaleXAnimator = ObjectAnimator
.ofFloat(imageView, "scaleX", 1f, 1.5f);
scaleXAnimator.setDuration(500);
scaleXAnimator.setRepeatCount(1);
scaleXAnimator.setRepeatMode(ValueAnimator.REVERSE);
scaleXAnimator.start();
ObjectAnimator scaleYAnimator = ObjectAnimator
.ofFloat(imageView, "scaleY", 1f, 1.5f);
scaleYAnimator.setDuration(500);
scaleYAnimator.setRepeatCount(1);
scaleYAnimator.setRepeatMode(ValueAnimator.REVERSE);
animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
animatorSet.start();
}
上述代码通过playTogether函数实现两个动画同时执行,如果不想同时执行,也可以调用play函数返回AnimatorSet.Builder实例,AnimatorSet.Builder提供了如下几个函数用于实现动画组合:
1,after(Animator anim) 将现有动画插入到传入的动画之后执行
2,after(long delay) 将现有动画延迟指定毫秒后执行
3,before(Animator anim) 将现有动画插入到传入的动画之前执行
4,with(Animator anim) 将现有动画和传入的动画同时执行
也可以调用playSequentially函数实现分布执行动画。
方式二:使用PropertyValuesHolder
/*
通过这种方式只能实现同时执行的动画组合相比AnimatorSet就没那么丰富了,
PropertyValuesHolder 提供的函数方法有如下几种:
ofInt()、ofFloat()、ofObject()、ofKeyframe()。
*/
public void initPropertyValuesHolder() {
PropertyValuesHolder scaleXValuesHolder = PropertyValuesHolder
.ofFloat("scaleX", 1.0f, 1.5f);
PropertyValuesHolder scaleYValuesHolder = PropertyValuesHolder
.ofFloat("scaleY", 1.0f, 1.5f);
ObjectAnimator objectAnimator = ObjectAnimator
.ofPropertyValuesHolder(imageView,
scaleXValuesHolder, scaleYValuesHolder);
objectAnimator.setDuration(500);
objectAnimator.setRepeatCount(1);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
objectAnimator.start();
}
方式三:使用ViewPropertyAnimator
/*
多属性动画,作用于View,能够实现的动画相对单一,只能实现比如缩放,透明度改变,
平移、旋转等,具体函数名字:平移 translationX,translationY, X,Y,
缩放 scaleX,scaleY, 旋转 rotationX, rotationY,透明度 alpha
*/
public void initViewPropertyAnimator() {
ViewPropertyAnimator viewPropertyAnimator = imageView.animate();
viewPropertyAnimator.scaleXBy(1.0f).scaleX(1.5f)
.scaleYBy(1.0f).scaleY(1.5f).setDuration(500).start();
}
设置动画监听器
addListener
有时候我们可能要在某一个动画执行之前或者动画结束之后进行一些其他的操作,这个时候就要借助动画监听器了。
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//TODO 动画开始前的操作
}
@Override
public void onAnimationEnd(Animator animation) {
//TODO 动画结束的操作
}
@Override
public void onAnimationCancel(Animator animation) {
//TODO 动画取消的操作
}
@Override
public void onAnimationRepeat(Animator animation) {
//TODO 动画重复的操作
}
});
AnimatorUpdateListener
如果我们需要简单动画执行过程中的变化可以使用AnimatorUpdateListener
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
//可以根据自己的需要来获取动画更新值。
Log.e("AnimatorUpdateListener", "the animation value is " + value);
}
});