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

时间:2017-05-04 08:59:57

标签: java android canvas handler ondraw

我每次要绘制新的矩形时都会使用Handler延迟时间来调用onDraw,但是每个新的矩形都会删除前一个矩形。
如何使画布保持所有矩形的内容: 我的代码:

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);
        }
    }
}

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

你快要完成了!在致电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();
}

答案 2 :(得分:0)

对我而言,这种逻辑运作良好

@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);
            }
        }
    }

答案 3 :(得分:0)

最简单的方法是将canvas对象保持为类级别变量,并始终在此画布对象上绘制,并在此画布上的super.onDraw()传递中,它将始终保留您之前绘制的矩形