如何在 android 中对圆弧的绘制进行动画处理
How to animate the drawing of arc in android
我是 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();
有人可以建议这有什么问题或者可以建议一些其他的想法来制作动画。
Android 最重要的编程规则之一是你应该尽可能地限制你在 onDraw
中所做的事情。理想情况下,您不应在 onDraw
方法中分配任何内容。只是借鉴 canvas
.
不幸的是,这只是您的代码的第一个错误。
您应该这样考虑:单个 canvas
对象仅在单个 (simple) 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)
}
}
整个 "animation" 代码架构也可以做得更好。但主要问题在于 canvas
交互,所以我在您的代码中更正了这一点。
- 最好创建一个自定义视图 class 说 "ArcView" 这将扩展视图 class。然后在 onDraw 方法中添加绘制代码。
- 对于动画,您可以单独编写 class 这将扩展动画 class
- 将您的自定义视图传递给 Animation class 并在 applyTransformation() 方法下计算角度,然后将其设置为您的自定义视图并使视图无效。
你已经完成了 Arc 和漂亮的动画。
查看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;
}
}
动画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();
}
}
在 Activity 中,您可以使用以下代码来实例化弧形视图。
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" />
我是 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();
有人可以建议这有什么问题或者可以建议一些其他的想法来制作动画。
Android 最重要的编程规则之一是你应该尽可能地限制你在 onDraw
中所做的事情。理想情况下,您不应在 onDraw
方法中分配任何内容。只是借鉴 canvas
.
不幸的是,这只是您的代码的第一个错误。
您应该这样考虑:单个 canvas
对象仅在单个 (simple) 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)
}
}
整个 "animation" 代码架构也可以做得更好。但主要问题在于 canvas
交互,所以我在您的代码中更正了这一点。
- 最好创建一个自定义视图 class 说 "ArcView" 这将扩展视图 class。然后在 onDraw 方法中添加绘制代码。
- 对于动画,您可以单独编写 class 这将扩展动画 class
- 将您的自定义视图传递给 Animation class 并在 applyTransformation() 方法下计算角度,然后将其设置为您的自定义视图并使视图无效。
你已经完成了 Arc 和漂亮的动画。
查看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;
}
}
动画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();
}
}
在 Activity 中,您可以使用以下代码来实例化弧形视图。
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" />