如何使用onAnimationend()逐个启动动画?

时间:2015-07-11 07:48:16

标签: android animation view progress-bar interpolation

我正在制作一个由七个圆圈组成的动画。

我在画布上使用插补器和绘制圆圈,动画非常好。但我希望每个圈子一个接一个地开始(一个接一个)/

enter image description here

我为此开发了一个库项目,以下是我的java文件。

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.util.Log;
import android.view.animation.LinearInterpolator;

import teamdapsr.loaders.lib.utils.MeasureUtils;

/**
 * Created by Devesh on 08-Jul-15.
 */
public class CubicBezierRotate extends View{

    private int i=0;
    private int radius = 0, centerx, centery;
    private ShapeDrawable circleOne, circleTwo, circleThree, circlesmall;
    protected Paint paint[];
    protected ValueAnimator anim1, anim2, anim3;
    public int getRadius(){ return radius; }
    public void setRadius(int radius){ this.radius = radius; }

    public CubicBezierRotate(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.CubicBezierRotate,
                0, 0
        );

        try
        {
            radius = a.getInt(R.styleable.CubicBezierRotate_radius, 0);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            a.recycle();
        }
        init();
    }

    protected void init()
    {
        circleOne = new ShapeDrawable(new OvalShape());
        circleTwo = new ShapeDrawable(new OvalShape());
        circleThree = new ShapeDrawable(new OvalShape());


        circleOne.getPaint().setColor(0x99ff0000);
        circleTwo.getPaint().setColor(0x9900ff00);
        circleThree.getPaint().setColor(0x990000ff);

        ObjectAnimator animator = ObjectAnimator.ofInt(this, "radius", 0, 100);
        animator.setDuration(5000);
        animator.setInterpolator(new AnticipateOvershootInterpolator());

/*      Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    while(true) {
                        sleep(50);
                        updateBounds();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };*/


        paint = new Paint[3];

        paint[0] = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint[1] = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint[2] = new Paint(Paint.ANTI_ALIAS_FLAG);

        paint[0].setStyle(Paint.Style.FILL);
        paint[1].setStyle(Paint.Style.FILL);
        paint[2].setStyle(Paint.Style.FILL);

        paint[0].setColor(0x99999999);
        paint[1].setColor(0x99999999);
        paint[2].setColor(0x99999999);

    }

    protected void setupAnimations()
    {

        anim1 = ValueAnimator.ofInt(0, (int)(0.10*getMeasuredHeight()));
        anim2 = ValueAnimator.ofInt(0, (int)(0.10*getMeasuredHeight()));
        anim3 = ValueAnimator.ofInt(0, (int)(0.10*getMeasuredHeight()));

        anim1.setDuration(1500);
        anim2.setDuration(1500);
        anim3.setDuration(1500);

        anim1.setInterpolator(new AccelerateDecelerateInterpolator());
        anim2.setInterpolator(new LinearInterpolator());
        anim3.setInterpolator(new AnticipateOvershootInterpolator());

        anim1.setRepeatMode(ValueAnimator.REVERSE);
        anim2.setRepeatMode(ValueAnimator.REVERSE);
        anim3.setRepeatMode(ValueAnimator.REVERSE);

        anim1.setRepeatCount(ValueAnimator.INFINITE);
        anim2.setRepeatCount(ValueAnimator.INFINITE);
        anim3.setRepeatCount(ValueAnimator.INFINITE);

//      anim2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//          @Override
//          public void onAnimationUpdate(ValueAnimator animation) {
//              int animProgress = (Integer) animation.getAnimatedValue();
//          }
//      });
//
//      anim1.addListener(new AnimatorListenerAdapter() {
//          @Override
//          public void onAnimationEnd(Animator animation) {
//              super.onAnimationEnd(animation);
//          }
//      });
        anim1.start();
        anim2.start();
        anim3.start();
    }
    protected void updateBounds(int radius)
    {
/*
        circleOne.setBounds(radius, radius, radius, radius);
        circleTwo.setBounds(radius, radius, radius, radius);
        circleThree.setBounds(radius, radius, radius, radius);
*/

        invalidate();
        //requestLayout();
    }

    @Override
    public void onDraw(Canvas canvas)
    {

            Log.i("radius", "Radius1 = " + (int) (anim1.getAnimatedValue()));
            Log.i("radius", "Radius2 = " + (int) (anim2.getAnimatedValue()));
            Log.i("radius", "Radius3 = " + (int) (anim3.getAnimatedValue()));

        canvas.drawCircle(50, getMeasuredHeight()/2, (int)(anim1.getAnimatedValue()), paint[0]);

        canvas.drawCircle(90, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[1]);

        canvas.drawCircle(130, getMeasuredHeight()/2, (int)(anim3.getAnimatedValue()), paint[2]);
        canvas.drawCircle(170, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
            canvas.drawCircle(210, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
            canvas.drawCircle(250, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
            canvas.drawCircle(290, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);


//      while (i<7)
//      {
//          switch (i)
//          {
//              case 0 :
//                  canvas.drawCircle(50, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[0]);
//                  canvas.drawCircle(90, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[1]);
//                  canvas.drawCircle(130, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
//                  canvas.drawCircle(170, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
//                  try {
//                      Thread.sleep(1000);
//                  } catch (InterruptedException e) {
//                      e.printStackTrace();
//                  }
//                  i++;
//                  break;
//              case 1 :
//
//                  canvas.drawCircle(210, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
//                  canvas.drawCircle(250, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
//                  canvas.drawCircle(290, getMeasuredHeight()/2, (int)(anim2.getAnimatedValue()), paint[2]);
//                  try {
//                      Thread.sleep(50);
//                  } catch (InterruptedException e) {
//                      e.printStackTrace();
//                  }
//                  break;
//
//          }
//      }
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        updateBounds(0);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // Get the width measurement
        int widthSize = MeasureUtils.getMeasurement(widthMeasureSpec, getDesiredWidth());

        // Get the height measurement
        int heightSize = MeasureUtils.getMeasurement(heightMeasureSpec, getDesiredHeight());

        centerx = (int)(0.5*MeasureSpec.getSize(widthMeasureSpec));
        centery = (int)(0.5*MeasureSpec.getSize(heightMeasureSpec));

        //MUST call this to store the measurements
        setMeasuredDimension(widthSize + 10, heightSize + 10);

        setupAnimations();
    }

    private int getDesiredWidth()
    {
        // TO-DO Calculate width from child components.

        return 2*radius+1000;
    }

    private int getDesiredHeight()
    {
        // TO-DO Calculate height from chile components.
        return 2*radius+100;
    }

}

请帮帮我。 我想逐个开始每个圆圈动画(下一个圆圈仅在前一个圆圈结束时开始)。 整个周期就像“1 2 3 4 5 6 7”然后从结尾“7 6 5 4 3 2 1”

1 个答案:

答案 0 :(得分:0)

为什么不使用animation-list? 。

第1步:为动画的每一步定义图像

第2步:创建一个可绘制的xml文件,该文件应该包含这样的内容(动画7个圆圈的示例):

<animation-list   android:id="@+id/progressCircles" android:oneshot="false" 
         xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/progress_circle1" android:duration="150" />
        <item android:drawable="@drawable/progress_circle2" android:duration="150" />
        <item android:drawable="@drawable/progress_circle3" android:duration="150" />
        <item android:drawable="@drawable/progress_circle4" android:duration="150" />
        <item android:drawable="@drawable/progress_circle5" android:duration="150" />
        <item android:drawable="@drawable/progress_circle6" android:duration="150" />
        <item android:drawable="@drawable/progress_circle7" android:duration="150" />
     </animation-list> 

第3步:在布局文件中创建ImageView,并将progressCircles设置为图像的android:src

<ImageView
  android:id="@+id/progress_bar"
  android:layout_alignParentRight="true"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:src="@drawable/progressCircles" />

第4步(Optionnal):检索对图像和AnimationDrawable的引用,以便跟踪进度,例如:

ImageView imgProgress = (ImageView)findViewById(R.id.progress_bar);
    if (imgProgress != null) {
        imgProgress.setVisibility(View.VISIBLE);
        AnimationDrawable animation = (AnimationDrawable)progress.getDrawable();
        animation.setCallback(progress);
        animation.setVisible(true, true);
    }