Complete Analysis of Property Animation

Keywords: Attribute Android

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

iv.setRotationX(180);
But you can't set the delay. The effect is simple.

Next is the basic use of attribute animation.

                ObjectAnimator animator = ObjectAnimator.ofFloat(v, "translationX", 0, 400);
                animator.setDuration(500);
                animator.start();
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, "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();
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 above
            ValueAnimator 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();
The last method
                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();
tips:

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.

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);
Finally, an attribute animation of parabola is realized.
                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

    private 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;
    }
Route animation

    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;
    }
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.

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;
    }
}
The evaluate here is based on the cubic equation of the Bessel curve.




Posted by OOP on Fri, 29 Mar 2019 09:45:29 -0700