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

У меня есть пользовательский вид в моем приложении, который заполняет всю активность.

В большинстве случаев, когда я хочу обновить элемент управления, я вызываю invalidate() без каких-либо параметров.

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

Это работает отлично, однако, когда я включаю аппаратное ускорение в Honeycomb (т.е. устанавливаю android:hardwareAccelerated="true" в AndroidManifest.xml), частичное перерисовка не работает.

Это можно увидеть, если я выполняю Log.d("FOO", canvas.getClipBounds()) в методе onDraw(); выход просто показывает, что весь элемент управления обновляется, а при отключении аппаратного ускорения я получаю правильную область вывода.

Есть ли способ сделать частичную недействительность работы при использовании аппаратного ускорителя?

Большое спасибо, Matt

Ответ 1

Частичная перерисовка работает просто отлично, перерисовывается только указанная область экрана. Однако этого не произойдет, если вы измените границы клипа на холсте. Все операции рисования будут записаны, но только те, которые пересекаются с грязной областью, будут фактически выполнены.

Обновление: по состоянию на Lollipop (API 21) частичная аннулирование происходит на уровне просмотра (т.е. Вы не можете сделать недействительной меньше, чем весь вид).

Ответ 2

Когда HA включена, конвейер рендеринга будет использовать DisplayList для хранения команд рисования. Даже если вы укажете грязную область в View.invalidate, весь список отображения будет перестроен (просто подумайте, как мы можем обновить только небольшой набор DisplayList, что невозможно?). В конце концов, как @Romain говорит, что только реальный грязный регион будет перерисован.