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

FiX*_*XiT 4 animation android 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();
Run Code Online (Sandbox Code Playgroud)

有人可以建议这里有什么错误或者可以建议一些其他动画的想法.

小智 11

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

你完成了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;
    } 
}
Run Code Online (Sandbox Code Playgroud)

动画类

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在Activity中,您可以使用以下代码来实例化弧视图.

 ArcView arcView = (ArcView) findViewById(R.id.arcView);
    ArcAngleAnimation animation = new ArcAngleAnimation(arcView, 360);
    animation.setDuration(1000);
    arcView.startAnimation(animation);
Run Code Online (Sandbox Code Playgroud)

内部布局,

    <com.graph.app.Test.ArcView
       android:id="@+id/arcView"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
Run Code Online (Sandbox Code Playgroud)


Bar*_*ski 6

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

整个“动画”代码架构也可以更好。但主要问题在于canvas交互,所以这就是我在您的代码中更正的问题。