Частичная аннулирование Android рисует весь вид, в то время как аппаратное ускорение

Я написал Activity, которая показывает только один пользовательский вид.

Вид прост: нарисуйте случайный цвет и сделайте недействительной меньшую область, нарисуйте случайный цвет и сделайте недействительной еще меньшую область и так далее...

Ожидаемый результат должен быть таким. Это хорошо работает при использовании программного рендеринга, а getClipBounds() возвращает область, которую я только что передал, в аннулирование. Но когда аппаратное ускорение включено, весь вид всегда перерисовывается новым цветом, и getClipBounds() возвращает всю область представления.

Я знаю, что есть такие сообщения, как это и это. Ответы сказали, что getClipBounds() возвращает всю область представления с аппаратным ускорением, но будут перерисованы только те, которые пересекают грязную область.

Что-то не так или мое недоразумение?

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

    // random color
    int color = Color.rgb((int) (Math.random() * 255),
            (int) (Math.random() * 255), (int) (Math.random() * 255));

    canvas.drawColor(color);

    canvas.getClipBounds(rect);

    // smaller dirty region
    invalidate(0, 0, rect.width() - 1, rect.height() - 1);
}

1 ответ

К сожалению, это ограничение аппаратного ускорения Android, по крайней мере, для Android 5. Прямоугольник недействительности игнорируется, и весь вид всегда перерисовывается, что требует рисования всей области. Если вы попытаетесь нарисовать только часть вида, все, что было нарисовано ранее, исчезнет.

Я читал посты, в которых утверждается, что Android не рендерит весь вид, а только часть, которая изменилась, но это кажется неправильным, потому что, когда я пытаюсь сделать только ту область, которая была в прямоугольнике, которую я передал, чтобы сделать недействительным, сброс представления исчезает. Если бы это было правдой, то Android переопределял только измененную область, тогда я ожидал бы, что остальная часть пользовательского чертежа в представлении останется видимой.

iOS имеет гораздо лучшую производительность благодаря своему методу drawRect и setNeedsDisplayInRect. Я бы ожидал, что Android будет работать так же, но, увы, нет.

Другие вопросы по тегам