如何在android中设置arc的绘制动画

时间:2016-06-08 17:34:14

标签: android animation android-canvas

我是Android的新手,我使用drawArc函数向用户显示某些任务的进度,但现在我想对其进行动画处理,使其看起来好像正在增长。

我使用以下代码但不能正常工作:

   new Thread(new Runnable() {
    int i=0;
    float startAngle =0;
    float swipeAngle = 40.7f;
    public void run() {
        while (i < swipeAngle) {
            canvas.drawArc(rectF, startAngle, i, false, paint);

            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        i++;
    }
}).start();

有人可以建议这里有什么错误,或者可以提出一些其他想法来制作动画。

2 个答案:

答案 0 :(得分:10)

  1. 更好地创建一个自定义视图类,说“ArcView”,它将扩展View类。然后在onDraw方法中添加绘图代码。
    1. 对于动画,您可以编写单独的类,它将扩展Animation类
    2. 将您的自定义视图传递给Animation类,然后在applyTransformation()方法下,计算角度,然后将其设置为自定义视图并使视图无效。
  2. 你完成了Arc,动画很棒。

    查看课程

    public class ArcView extends View {
    
    private final Paint mPaint;
    private final RectF mRect;
    private float arcAngle;
    
        public ArcView(Context context, AttributeSet attrs) {
    
        super(context, attrs);
    
        // Set Angle to 0 initially
        arcAngle = 0;
    
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(20);
        mPaint.setColor(Color.RED);
        mRect = new RectF(20, 20, 220, 220);
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawArc(mRect, 90, arcAngle, false, mPaint);
        }
    
        public float getArcAngle() {
        return arcAngle;
        }
    
        public void setArcAngle(float arcAngle) {
        this.arcAngle = arcAngle;
        } 
    }
    

    动画类

    public class ArcAngleAnimation extends Animation {
    
    private ArcView arcView;
    
    private float oldAngle;
    private float newAngle;
    
        public ArcAngleAnimation(ArcView arcView, int newAngle) {
        this.oldAngle = arcView.getArcAngle();
        this.newAngle = newAngle;
        this.arcView = arcView;
        }
    
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation transformation) {
        float angle = 0 + ((newAngle - oldAngle) * interpolatedTime);
    
        arcView.setArcAngle(angle);
        arcView.requestLayout();
        }
    }
    

    在“内部活动”中,您可以使用以下代码来实例化弧视图。

     ArcView arcView = (ArcView) findViewById(R.id.arcView);
        ArcAngleAnimation animation = new ArcAngleAnimation(arcView, 360);
        animation.setDuration(1000);
        arcView.startAnimation(animation);
    

    内部布局,

        <com.graph.app.Test.ArcView
           android:id="@+id/arcView"
           android:layout_width="match_parent"
           android:layout_height="match_parent" />
    

答案 1 :(得分:4)

Android最重要的编程规则之一就是你应该尽可能地限制你在onDraw中所做的事情。理想情况下,您不应该使用onDraw方法分配任何内容。只需了解canvas

不幸的是,这只是代码中的第一件事。

您应该这样考虑:单个canvas对象仅在单个(简单onDraw方法调用期间可行。所以你不能在一个单独的线程中重用它。

对于您的情况,您应该开始一个单独的线程(就像您在示例中所做的那样),但在其中,您应该只更新代表弧角的View's字段并询问您的View重绘(invalidate()方法)。

public class TestView extends View {

    private float currentAngle;

    //... some needed methods (be sure to init rectF and paint somewhere here)

    public void startAnimatingArc(final float maxAngle) {
        currentAngle = 0;
        new Thread(new Runnable() {
            public void run() {
                while (currentAngle < maxAngle) {
                    invalidate();
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                currentAngle++;
            }
        }).start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawArc(rectF, 0, currentAngle, false, paint);
        // you should try not to add anything else in this call
        // (unless you want to draw something else as well)
    }
}

整个“动画”代码架构也可以更好。但主要的问题是canvas互动,所以我在你的代码中纠正了这一点。