Android: Как получить пользовательский вид, чтобы частично перерисовать?
У меня есть пользовательский вид, который заполняет весь экран. (Фортепианная клавиатура)
Когда пользователь прикасается к ключу, он вызывает вызов invalidate()
, и вся клавиатура перерисовывается, чтобы показать новое состояние с помощью троянца.
В настоящее время представление очень простое, но я планирую добавить немного более приятную графику. Поскольку вся клавиатура динамически визуализируется, это сделает перерисовку всей клавиатуры более дорогой.
Итак, я подумал, давайте посмотрим на частичную перерисовку. Теперь я вызываю invalidate(Rect dirty)
с правильной грязной областью. Я установил метод onDraw(Canvas canvas)
только для рисования ключей в грязной области, если я действительно хочу частично перерисовать. Это приводит к рисованию этих клавиш, но остальная часть клавиатуры полностью черная/не нарисована вообще.
Я ошибаюсь в ожидании, что вызов invalidate(Rect dirty)
будет "кэшировать" текущий canvas
и только "разрешает" рисование в грязном регионе?
Есть ли способ добиться того, чего я хочу? (Способ "кешировать" холст и только перерисовывать грязную область? "
Ответы
Ответ 1
Текущее удобное обходное решение - вручную кэшировать полный холст в растровое изображение:
private void onDraw(Canvas canvas)
{
if (!initialDrawingIsPerformed)
{
this.cachedBitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Config.ARGB_8888); //Change to lower bitmap config if possible.
Canvas cacheCanvas = new Canvas(this.cachedBitmap);
doInitialDrawing(cacheCanvas);
canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint());
initialDrawingIsPerformed = true;
}
else
{
canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint());
doPartialRedraws(canvas);
}
}
Конечно, вам нужно сохранить информацию о том, что нужно перерисовать, и желательно не использовать новый Paint
каждый раз, но это подробности.
Также обратите внимание: растровые изображения довольно сильно зависят от использования вашего приложения в памяти. У меня были сбои, когда я кэшировал View, который использовался со скроллером, и это было в 5 раз больше высоты устройства, так как оно использовало > 10 МБ памяти!
Ответ 2
Чтобы дополнить ответ Peterdk, вы можете сохранить свои операции в картинке вместо растрового изображения.
- Растровое изображение сохранит все пиксели, например
он сказал, что может потребоваться много
память.
- Изображение сохранит
вызовы, такие как drawRect, drawLine и т.д.
Это зависит от того, что действительно тяжело в вашем приложении: много операций рисования, нескольких операций рисования, но контролируется большими вычислениями, большим количеством пустого/неиспользуемого пространства (предпочтительнее изображение) и т.д.