动画以编程方式创建的椭圆GradientDrawable

时间:2014-02-06 12:22:14

标签: android android-animation android-drawable

我以编程方式创建了以下椭圆形GradientDrawable来显示圆圈:

GradientDrawable drawable = new GradientDrawable();
drawable.setColor(Color.TRANSPARENT);
drawable.setShape(GradientDrawable.OVAL);
drawable.setStroke(wheelStrokeWidth, Color.parseColor(WHEEL_STROKE_COLOR)); 
drawable.setSize(2*wheelRadius+wheelStrokeWidth,2*wheelRadius+wheelStrokeWidth);

ImageView iv = new ImageView(activity);
iv.setImageDrawable(drawable);

我想动画这个圆圈的绘图,使其逐渐绘制。首先它只是一个0°的弧度,然后是1°,然后逐渐进入一个完整的360°圆圈(对不起,如果我不清楚,很难用英语表达)。

任何人都知道如何做到这一点?

谢谢!

2 个答案:

答案 0 :(得分:0)

这不是一个完美的解决方案。但这可能会给你一些想法。

public class MyView extends View {

private Bitmap mBitmap;
private Paint mPaint;
private RectF mOval;
private float mAngle = 135;
private Paint mTextPaint;

public MyView(Context context) {
    super(context);
    // use your bitmap insted of R.drawable.ic_launcher
    mBitmap = BitmapFactory.decodeResource(getResources(),
            R.drawable.image1);
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mOval = new RectF();
    mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mTextPaint.setTextSize(48);
    mTextPaint.setTextAlign(Align.CENTER);
    mTextPaint.setColor(0xffffaa00);
    mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    Matrix matrix = new Matrix();
    RectF src = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
    RectF dst = new RectF(0, 0, w, h);
    matrix.setRectToRect(src, dst, ScaleToFit.CENTER);
    Shader shader = new BitmapShader(mBitmap, TileMode.CLAMP,
            TileMode.CLAMP);
    shader.setLocalMatrix(matrix);
    mPaint.setShader(shader);
    matrix.mapRect(mOval, src);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(0xff0000aa);
    canvas.drawArc(mOval, -90, mAngle, true, mPaint);
    canvas.drawText("click me", getWidth() / 2, getHeight() / 2,
            mTextPaint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float w2 = getWidth() / 2f;
    float h2 = getHeight() / 2f;
    mAngle = (float) Math.toDegrees(Math.atan2(event.getY() - h2,
            event.getX() - w2));
    mAngle += 90 + 360;
    mAngle %= 360;
    if (mAngle == 0) {
        mAngle = 360;
    }
    invalidate();
    return true;
}
}

并且Credit会转到其他用户身上。他在某些地方发布了这个解决方案(我忘了),然后我用了......

答案 1 :(得分:0)

通过关注这篇文章的想法:Android custom Animation for an ArcShape,我将GradientDrawable更改为自定义视图,并使此类逐步绘制弧:

/**
 * An arc with an animation to draw it progressively
 *
 * Usage:
 *
 * AnimatedArc aa = new AnimatedArc(...)
 * AnimatedArc.ProgressiveDrawing animation = aa.getAnimation(...)
 * aa.startAnimation(animation)
 */

public class AnimatedArc extends View {

    int delta, startAngle, sweepAngle, currentSweepAngle;

    Paint p = new Paint();
    Rect rect = new Rect();
    RectF rectF = new RectF();

    public AnimatedArc(Context context, int strokeWidth, String color, int startAngle, int sweepAngle, boolean doNotAnimate) {

        super(context);

        p.setAntiAlias(true);
        p.setColor(Color.parseColor(color));
        p.setStyle(Paint.Style.STROKE);
        p.setStrokeWidth(strokeWidth);

        delta = strokeWidth / 2;

        this.startAngle = startAngle;
        this.sweepAngle = sweepAngle;
        this.currentSweepAngle = doNotAnimate ? sweepAngle : 0;
    }

    public ProgressiveDrawing getAnimation(int duration) {
        return new ProgressiveDrawing(duration);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.getClipBounds(rect);
        rectF.set(rect.left+delta, rect.top+delta, rect.right-delta, rect.bottom-delta);
        canvas.drawArc(rectF, startAngle, currentSweepAngle, false, p);
    }

    public class ProgressiveDrawing extends Animation {

        public ProgressiveDrawing(int duration) {
            setDuration(duration);
            setInterpolator(new LinearInterpolator());
        }

        public ProgressiveDrawing(int duration, Interpolator interpolator) {
            setDuration(duration);
            setInterpolator(interpolator);
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            currentSweepAngle = (int) (sweepAngle * interpolatedTime);
            postInvalidate();
        }
    }
}