Preface
From complementary animation, frame animation to attribute animation, the effect of animation is more and more abundant and perfect.
Tween Animation
a. Types of Gradient Painting Support: Translate, Rotate, Scale, Alpha
b. The actual position of the View does not change just because the display position changes. When the View moves, the click event can only respond in its place.
c. Composite use is very complex
Frame Animation
a. Used to generate continuous Gif renderings
b. Drawable Animation means this animation
Property Animation
a. Support for animation of attributes that can be updated for all View s (set and get methods that require attributes)
b. Change the actual properties of View, so the click event is at the end of the animation.
c, Android 3.0 (API 11), before 3.0, you can use third-party open source library nineold and roids. jar for support.
Part 1. Use of Property Animation
The simplest use
But you can't set the delay. The effect is simple.iv.setRotationX(180);
Next is the basic use of attribute animation.
This is how a simple translation painting is done. Besides, you can use other methods to achieve the same effect.ObjectAnimator animator = ObjectAnimator.ofFloat(v, "translationX", 0, 400); animator.setDuration(500); animator.start();
It should be noted here that propertyName is an attribute that does not exist in View. Even if it does not exist, it will change from 0 to 400 in 500 milliseconds. Just listen to updateListener to animate View in it. Same code as aboveObjectAnimator animator = ObjectAnimator.ofFloat(v, "andly", 0, 400); animator.setDuration(500); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //animation.getAnimatedFraction();// Percentage //Get an intermediate value of values in duration time. float value = (float) animation.getAnimatedValue(); //animation.getCurrentPlayTime(); iv.setTranslationX(value); } }); animator.start();
The last methodValueAnimator animator = ValueAnimator.ofFloat(0,400); animator.setDuration(500); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { iv.setTranslationX((Float) animation.getAnimatedValue()); } }); animator.start();
tips:PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 0, 300, 500); PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("rotationX", 0, 180, 360); ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(v, pvh1,pvh2); animator.setDuration(500); animator.start();
1...... Values uses three parameters, 0-300 300-500, and takes 250 hours per period.
2. Property Value Holder can add keyframes (time/value pairs) to it, allowing you to define a specific state at a specific time of the animation. Each key frame can also have its own interpolator to control the behavior of the animation in the interval between the time of the last key frame and the time of that key frame.
Finally, an attribute animation of parabola is realized.Keyframe kf0 = Keyframe.ofFloat(0f, 0f); Keyframe kf1 = Keyframe.ofFloat(.5f, 360f); Keyframe kf2 = Keyframe.ofFloat(1f, 0f); PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2); ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation) rotationAnim.setDuration(5000ms);
ValueAnimator animator = new ValueAnimator(); animator.setDuration(1000); animator.setObjectValues(new PointF(0,0));//Determine the type of Value Animator to use animator.setEvaluator(new TypeEvaluator<PointF>() { @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { PointF pointF = new PointF(); pointF.x = 20 * (fraction * 10);//20 for speed 10 for total time pointF.y = 0.5f * 9.8f * (fraction * 10) * (fraction * 10); return pointF; } }); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF pointF = (PointF) animation.getAnimatedValue(); iv.setX(pointF.x); iv.setY(pointF.y); } }); animator.start();
Of course, you can also add accelerators to your animation.
Part 2. Romantic gift brushing effect
Effect ~
Analysis: There are two kinds of central picture animation: 1. Display animation (zoom, transparency effect) 2. Route (Bessel curve) 3. Vanishing animation.
Self animation
Route animationprivate AnimatorSet getBasicAnimation(ImageView iv) { ObjectAnimator ap = ObjectAnimator.ofFloat(iv, "alpha", 0.1f, 1.0f); ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 0.1f, 1.0f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 1.0f); AnimatorSet set = new AnimatorSet(); set.playTogether(ap, scaleX, scaleY); set.setTarget(iv); return set; }
A custom interpolator is used here to define the calculation rules, allowing the location and transparency of the ImageView to be changed in the Animation Update method.private ValueAnimator getIVAnimator(final ImageView iv) { final PointF point0 = new PointF(0, height); PointF point1 = new PointF(random.nextInt(width), random.nextInt(height)); PointF point2 = new PointF(random.nextInt(width), random.nextInt(height)); PointF point3 = new PointF(random.nextInt(width), 0); MyTypeEvaluator myEvaluator = new MyTypeEvaluator(point1, point2); ValueAnimator valueAnimator = ValueAnimator.ofObject(myEvaluator, point0, point3); valueAnimator.setTarget(iv); valueAnimator.setDuration(3000); valueAnimator.setInterpolator(interpolators[random.nextInt(interpolators.length)]); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF pointF = (PointF) animation.getAnimatedValue(); iv.setX(pointF.x); iv.setY(pointF.y); iv.setAlpha(1 - animation.getAnimatedFraction()); } }); return valueAnimator; }
The evaluate here is based on the cubic equation of the Bessel curve.public class MyTypeEvaluator implements TypeEvaluator<PointF> { private PointF point1; private PointF point2; public MyTypeEvaluator(PointF point1, PointF point2) { this.point1 = point1; this.point2 = point2; } @Override public PointF evaluate(float t, PointF point0, PointF point3) { PointF point = new PointF(); point.x = point0.x * (1 - t) * (1 - t) * (1 - t) + point1.x * t * (1 - t) * (1 - t) + point2.x * t * t * (1 - t) + point3.x * t * t * t; point.y = point0.y * (1 - t) * (1 - t) * (1 - t) + point1.y * t * (1 - t) * (1 - t) + point2.y * t * t * (1 - t) + point3.y * t * t * t; return point; } }