如何在画布上绘制很多具有良好性能的矩形?

时间:2015-07-23 13:36:17

标签: android performance user-interface canvas 2d

我必须使用扇区,行和座位来渲染电影院大厅地图。 目前我有大约1000个座位(填充矩形)可供绘制,我正在为每个座位执行此操作:

canvas.drawRect(seatRect, seatPaint)

我的观点还必须支持缩放,滚动和投掷。 表现很糟糕。我尝试通过明确启用硬件加速来改进它,但没有任何改变,它似乎默认在我的Nexus 4(Api 22)上启用

你能否建议任何高速渲染大量矩形的方法?所以运动,缩放动画很流畅。

自定义视图类代码:

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();
    canvas.scale(mScaleFactor, mScaleFactor); // scaling support
    canvas.translate(mTranslateX, mTranslateY); // scrolling support

    if (mEventMap != null) {
        mEventMap.paint(canvas);
    }

    canvas.restore();
}

EventMap代码:

public void paint(Canvas canvas) {
    for (EventPlace place : places) {
        if (place.isSelected())
            placePaint.setColor(0xFF00FF00);
        else if (place.isAvailable())
            placePaint.setColor(place.getColor());
        else
            placePaint.setColor(0xFF000000);

        canvas.drawRect(place.getBounds(), placePaint);
    }
}

onDraw中调用的所有方法都不会创建任何实例。 只有很多矩形...

1 个答案:

答案 0 :(得分:2)

您现在遇到的主要问题基本上是您执行了大量的绘图周期(等于您拥有的Rect数量),最好将所有这些需求存储在{{3}中} object,以减少绘制周期数。由于您有三种座位状态,我建议创建三个路径。我建议做这样的事情:

private void init() {
    mSelectedPath = new Path();
    mAvailablePath = new Path();
    mUnavalablePath = new Path();

    mAvailablePaint = new Paint();
    mSelectedPaint = new Paint();
    mUnavalablePaint = new Paint();

    mUnavalablePaint.setColor(Color.RED);
    mSelectedPaint.setColor(Color.YELLOW);
    mAvailablePaint.setColor(Color.GREEN);

    for (EventPlace place : mData) {
        if (place.isSelected())
            mSelectedPath.addRect(rectF, Path.Direction.CW);
        else if (place.isAvailable())
            mAvailablePath.addRect(rectF, Path.Direction.CW);
        else
            mUnavalablePath.addRect(rectF, Path.Direction.CW);
    }
}

然后,当您想将日期与此视图关联时,您应该执行以下操作:

public void setData(List<EventPlace> data) {
    mData = data;
    init();
    invalidate();
}

实际上你可以随心所欲地做到这一点,只要记住你必须调用init方法然后失效。在onDraw中:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();
    canvas.scale(mScaleFactor, mScaleFactor); // scaling support
    canvas.translate(mTranslateX, mTranslateY); // scrolling support

    canvas.drawPath(mAvailablePath, mAvailablePaint);
    canvas.drawPath(mUnavalablePath, mUnavalablePaint);
    canvas.drawPath(mSelectedPath, mSelectedPaint);

    canvas.restore();
}

也许您还想添加一些逻辑来排除那些目前在路径中不可见的Rect,以便调整性能。

我尝试在Rects的测试集上设置动画我的方法,它运行顺利,有200个rects,但我没有尝试执行严格的基准测试