我是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();
有人可以建议这里有什么错误,或者可以提出一些其他想法来制作动画。
答案 0 :(得分:10)
你完成了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
互动,所以我在你的代码中纠正了这一点。