绘制多个矩形,它们之间有延迟

Draw multiple rectangles with delays between them

我正在使用 Handler post 延迟调用 onDraw 每次我想绘制新的矩形,但是对于每个新的矩形擦除前一个..
如何使 canvas 保留所有矩形的内容: 我的代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.CountDownTimer;
import android.os.Handler;
import android.util.Log;

import com.adhamenaya.microchart.model.ChartData;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by Admin on 18/12/2016.
 */

public class ColumnChart extends Chart implements Runnable {

    private int mSpace = 0;
    private int mColumnSize = 0;
    private int mColumnsCount = 0;
    private int mCurrentStart = 0;
    private float mHeightUnit = 0;
    private int mHeightDiff;
    int columnIndex = 0;

    private Handler mHandler;
    private Canvas mCanvas;
    private Iterator mDataIterator;

    static final long FRAME_TIME = 100;
    private ArrayList<Rect> rectangles = new ArrayList<Rect>();


    public ColumnChart(Context context) {
        super(context);
        mHandler = new Handler();
    }

    @Override
    protected void prepare() {
        if (mChartData != null && mChartData.getSingleData().size() > 0) {
            mColumnsCount = mChartData.getSingleData().size();

            // Column size, 1 is added to reserve a space at the end of the chart
            mColumnSize = (int) ((mWidth / (mColumnsCount)) * 0.9);

            // Calculate the space between the bars
            mSpace = (mWidth / mColumnsCount) - mColumnSize;

            // Calculate height unit
            // Calculate 80% of the total height
            float height08 = mHeight * 0.8f;
            mHeightUnit = height08 / mChartData.getMax();

            // Draw bars
            mDataIterator = mChartData.getSingleData().entrySet().iterator();

            mMainPaint = getRectPaint();


            // Create rect objects
            while (mDataIterator.hasNext()) {
                Map.Entry entry = (Map.Entry) mDataIterator.next();

                int columnHeight = (int) ((int) entry.getValue() * mHeightUnit);
                String key = (String) entry.getKey();

                // Shift the
                mCurrentStart += mSpace;

                // Calculate the difference between the total height and the height of the column
                mHeightDiff = mHeight - columnHeight;

                mCurrentStart += mColumnSize;

                mDataIterator.remove();

                Rect rect = new Rect(mCurrentStart, mHeightDiff,
                        mCurrentStart + mColumnSize, mHeight);
                rectangles.add(rect);
            }
        }
    }

    @Override
    protected void paintChart(Canvas canvas) {

    }

    @Override
    public void setData(ChartData data) {
        this.mChartData = data;
        prepare();
        mHandler.post(this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // Get measured height and width of the view
        setMeasuredDimension(getMeasurement(widthMeasureSpec, mWidth),
                getMeasurement(heightMeasureSpec, mHeight));

        // mWidth = MeasureSpec.getSize(widthMeasureSpec);
        // mHeight = MeasureSpec.getSize(heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(columnIndex > 0 && columnIndex<rectangles.size())
            canvas.drawRect(rectangles.get(columnIndex), getRectPaint());
    }

    @Override
    public void run() {

        if(columnIndex<rectangles.size()){
            invalidate();
            columnIndex++;
            mHandler.postDelayed(this,FRAME_TIME);
        }else{
            mHandler.removeCallbacks(this);
        }
    }
}

创建一个要在其上绘制矩形的 FrameLayout。每次绘制新圆时都创建一个视图。在新创建的视图上绘制圆圈并将该视图添加到 FrameLayout。默认情况下,视图的背景是透明的。如果不是,则将背景设置为透明。这样您以前的矩形将可见,新矩形将绘制在现有矩形上。

你快要完成了!在调用 invalidate 方法后调用你准备。

 @Override
public void run() {

    if(columnIndex<rectangles.size()){
        invalidate();
        columnIndex++;
        mHandler.postDelayed(this,FRAME_TIME);
    }else{
        mHandler.removeCallbacks(this);
        eraseAll();
    }
}

...

 public void eraseAll() {
    this.canvas.drawColor(0, PorterDuff.Mode.CLEAR);
    invalidate();
    prepare();
}

对我来说这个逻辑工作正常

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(columnIndex < rectangles.size()) {
            for (int i = 0; i <= columnIndex; ++i) {
                canvas.drawRect(rectangles.get(i), paint);
            }
        }
    }

最简单的做法是将 canvas 对象保留为 class 级别变量,并始终在此 canvas 对象上绘制,并在 super.onDraw() 中传递此 canvas,它会一直保持你之前绘制的矩形