【问题标题】:Animate an oval GradientDrawable created programmatically为以编程方式创建的椭圆 GradientDrawable 设置动画
【发布时间】:2014-02-06 12:22:14
【问题描述】:

我以编程方式创建了以下椭圆 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° 圆(对不起,如果我不清楚,很难用英语表达它)。

有人知道怎么做吗?

谢谢!

【问题讨论】:

    标签: android android-animation android-drawable


    【解决方案1】:

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

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

    并且信用归其他用户所有。他在某个地方(我忘了)发布了这个解决方案,我使用了那个......

    【讨论】:

    • 是我先发的
    • @pskink 好的...如果您有兴趣回答这个问题,我将删除我的答案:-)
    • 感谢您的回答。但我不明白。为什么要使用位图和canvas.drawArc?我的意思是,如果你画弧线,为什么需要位图?
    【解决方案2】:

    按照这篇文章的想法:Android custom Animation for an ArcShape,我将我的 GradientDrawable 更改为自定义 View,并让这个类逐步绘制弧线:

    /**
     * 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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-27
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多