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

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

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

Ожидаемый результат должен быть похож на этот. Он хорошо работает при использовании программного рендеринга, а 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);
}

person benny lu    schedule 30.04.2015    source источник
comment
Это похоже на ошибку/недостаток в Android. Весь вид всегда перерисовывается, и соответственно страдает производительность. Что я сделал в этих случаях, так это создал сетку представлений, которые переходят в родительское представление, и родитель достаточно умен, чтобы правильно аннулировать дочерние представления в сетке и отправить им правильный фрагмент растрового изображения для рисования.   -  person jjxtra    schedule 02.10.2015


Ответы (1)


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

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

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

person jjxtra    schedule 02.10.2015