在 canvas 上绘制多条线,中间有延迟
Drawing multiple lines on canvas with delay in between
几个月后,我终于成功创建了我的第一个重要应用程序。
现在我想添加一些漂亮的动画(不确定这是一个合适的术语),比如逐步绘制我的图表。下面的 Gif 解释了我需要什么。此时我的应用程序立即绘制图形,没有任何延迟。
在 MyFragment class 中有 FrameLayout,其中添加了自定义视图(我的图表):
public class MyFragment extends Fragment{
...
FrameLayout mFL;
MyDraw mydraw = new MyDraw(getContext(),floatArray_coord_X,floatArray_coord_Y);
mFL.addView(mydraw);
...
}
然后在我的自定义视图中 class 进行了一些计算并绘制了线条:
public class MyDraw extends View{
private Bitmap mBitmap;
private Canvas mCanvas;
...
@Override
public void onDraw(Canvas canvas){
mBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),
Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(bitmap);
...
// draw brown lines between two neighbour (X,Y) points
for (int i = 0; i < floatArray_coord_X.length - 1; i++) {
mCanvas.drawLine(floatArray_coord_X[i], floatArray_coord_Y[i],
floatArray_coord_X[i + 1], floatArray_coord_Y[i + 1],
mypaint0);
}
...
// draw black lines at calculated (X,Y) points
for (int i = 0; i < floatArray_coord_X_calc.length - 1; i++) {
mCanvas.drawLine(floatArray_coord_X_calc[i], floatArray_coord_Y_calc[i],
floatArray_coord_X_calc[i + 1], floatArray_coord_Y_calc[i + 1],
mypaint1);
}
...
// draw blue lines at newly calculated (X,Y) points
drawBlueLines(); // with extra calc
...
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
我试图通过使用 Handler/Runnable 来实现这一点 - 现在我知道在 onDraw 中调用它并不好(至少我的尝试并不好)...
有什么建议可以实现吗?
每次调用 View.onDraw()
方法都应该绘制图表的下一行,这看起来就像您描述的动画。要实现帧之间的延迟,您可以使用 View.postInvalidateDelayed()
:
private ArrayDeque<Point> mPoints = new ArrayDeque<>();
private Path mPath;
private Paint mPaint;
private int mBackgroundColor;
...
@Override
protected void onDraw(Canvas canvas) {
Point nextPoint = mPoints.pollFirst();
if (nextPoint != null) {
mPath.lineTo(nextPoint.x, nextPoint.y);
canvas.drawColor(mBackgroundColor);
canvas.drawPath(mPath, mPaint);
if (mPoints.size() > 0) {
postInvalidateDelayed(TimeUnit.SECONDS.toMillis(1));
}
}
}
public void drawChart(List<Point> points, int backgroundColor, int foregroundColor) {
mPoints.addAll(points);
mBackgroundColor = backgroundColor;
mPaint = new Paint();
mPaint.setColor(foregroundColor);
mPaint.setStrokeWidth(5);
mPaint.setStyle(Paint.Style.STROKE);
mPath = new Path();
mPath.moveTo(0,0);
postInvalidateDelayed(TimeUnit.SECONDS.toMillis(1));
}
从Activity开始动画:
ChartView chart = (ChartView) findViewById(R.id.chart);
List<Point> points = new ArrayList<>();
points.add(new Point(0, 200));
points.add(new Point(200, 200));
points.add(new Point(200, 0));
points.add(new Point(0,0));
chart.drawChart(points, Color.BLACK, Color.RED);
几个月后,我终于成功创建了我的第一个重要应用程序。 现在我想添加一些漂亮的动画(不确定这是一个合适的术语),比如逐步绘制我的图表。下面的 Gif 解释了我需要什么。此时我的应用程序立即绘制图形,没有任何延迟。
在 MyFragment class 中有 FrameLayout,其中添加了自定义视图(我的图表):
public class MyFragment extends Fragment{
...
FrameLayout mFL;
MyDraw mydraw = new MyDraw(getContext(),floatArray_coord_X,floatArray_coord_Y);
mFL.addView(mydraw);
...
}
然后在我的自定义视图中 class 进行了一些计算并绘制了线条:
public class MyDraw extends View{
private Bitmap mBitmap;
private Canvas mCanvas;
...
@Override
public void onDraw(Canvas canvas){
mBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(),
Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(bitmap);
...
// draw brown lines between two neighbour (X,Y) points
for (int i = 0; i < floatArray_coord_X.length - 1; i++) {
mCanvas.drawLine(floatArray_coord_X[i], floatArray_coord_Y[i],
floatArray_coord_X[i + 1], floatArray_coord_Y[i + 1],
mypaint0);
}
...
// draw black lines at calculated (X,Y) points
for (int i = 0; i < floatArray_coord_X_calc.length - 1; i++) {
mCanvas.drawLine(floatArray_coord_X_calc[i], floatArray_coord_Y_calc[i],
floatArray_coord_X_calc[i + 1], floatArray_coord_Y_calc[i + 1],
mypaint1);
}
...
// draw blue lines at newly calculated (X,Y) points
drawBlueLines(); // with extra calc
...
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
我试图通过使用 Handler/Runnable 来实现这一点 - 现在我知道在 onDraw 中调用它并不好(至少我的尝试并不好)... 有什么建议可以实现吗?
每次调用 View.onDraw()
方法都应该绘制图表的下一行,这看起来就像您描述的动画。要实现帧之间的延迟,您可以使用 View.postInvalidateDelayed()
:
private ArrayDeque<Point> mPoints = new ArrayDeque<>();
private Path mPath;
private Paint mPaint;
private int mBackgroundColor;
...
@Override
protected void onDraw(Canvas canvas) {
Point nextPoint = mPoints.pollFirst();
if (nextPoint != null) {
mPath.lineTo(nextPoint.x, nextPoint.y);
canvas.drawColor(mBackgroundColor);
canvas.drawPath(mPath, mPaint);
if (mPoints.size() > 0) {
postInvalidateDelayed(TimeUnit.SECONDS.toMillis(1));
}
}
}
public void drawChart(List<Point> points, int backgroundColor, int foregroundColor) {
mPoints.addAll(points);
mBackgroundColor = backgroundColor;
mPaint = new Paint();
mPaint.setColor(foregroundColor);
mPaint.setStrokeWidth(5);
mPaint.setStyle(Paint.Style.STROKE);
mPath = new Path();
mPath.moveTo(0,0);
postInvalidateDelayed(TimeUnit.SECONDS.toMillis(1));
}
从Activity开始动画:
ChartView chart = (ChartView) findViewById(R.id.chart);
List<Point> points = new ArrayList<>();
points.add(new Point(0, 200));
points.add(new Point(200, 200));
points.add(new Point(200, 0));
points.add(new Point(0,0));
chart.drawChart(points, Color.BLACK, Color.RED);