I am new to Android and I am using the drawArc function to show the progress of some task to the user but now I want to animate this so that it looks as if it is growing.
I use the following code but not working:
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();
Can Someone Please suggest whats wrong in this or Can suggest some other idea to animate.
You are done with Arc with nice animation.
View Class
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;
}
}
Animation Class
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();
}
}
Inside Activity, you can have below code to instantiate arc view.
ArcView arcView = (ArcView) findViewById(R.id.arcView);
ArcAngleAnimation animation = new ArcAngleAnimation(arcView, 360);
animation.setDuration(1000);
arcView.startAnimation(animation);
Inside layout,
<com.graph.app.Test.ArcView
android:id="@+id/arcView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
One of the most important rules of programming for Android is that you should limit things you do in onDraw
as much as you can. Ideally you shouldn't be allocating anything in onDraw
method. Just drawing on canvas
.
And unfortunately that's only the first thing that is wrong with your code.
You should think about it this way: a single canvas
object is only viable during a single (simple) onDraw
method call. So you cannot reuse it inside a separate thread.
For your case you should start a separate thread (just like you did in your example), but inside it you should only update a View's
field that represents the arc's angle and ask for your View
to redraw (the invalidate()
method).
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)
}
}
The whole "animation" code architecture could be much better as well. But the main problem is with the canvas
interaction, so that's what I corrected in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With