Оптимизация Функцией ScrollView
У меня есть scrollview, который содержит пользовательский вид. Пользовательский вид больше, чем площадь экрана, и рисует правильно.
однако scrollview имеет тенденцию вызывать onDraw() без остановки при прокрутке, и я не могу сделать его гладким.
Я использовал ScrollView.getDrawingRect() для вычисления видимой части экрана и только рисовать к этому, но он по-прежнему возвращает весь видовой экран (поэтому он оптимизирован, чтобы не рисовать области за пределами экрана), а не дельта между последняя позиция и текущая. В идеале я хотел бы нарисовать только дельту, а не все видимое окно.
Если кто-нибудь может указать мне больше информации о том, как использовать кэши чертежей, и если это поможет оптимизировать прокрутку, я хотел бы реализовать его или любые другие возможные решения, которые будут очень признательны.
3 ответов
при прокрутке содержимого весь видовой экран необходимо перерисовать, так как все содержимое перемещено. Я не думаю, что есть что-то, что нужно сделать, чтобы оптимизировать ScrollView
- Если прокрутка медленная, то это метод рисования вашего пользовательского представления, который слишком медленный.
старайтесь избегать создания объектов в ваших методах рисования, которые обычно являются основным виновником низкой производительности рисования.
Edit: также scrollview может blit старое содержимое вверх или вниз быстро, что по-прежнему рисуется на экране, а затем запросить перерисовку только "новой" части экрана. (применяется только к непрозрачным представлениям).
я столкнулся с той же проблемой. Я решил это, используя функцию setDrawingCacheEnabled(true)
. Включив этот параметр, представление canvas будет кэшироваться как растровое изображение, поэтому вам не нужно каждый раз вызывать метод рисования canvas onDraw()
называется.
в конструкторе настраиваемого представления, вам понадобится что-то вроде этого:
public CustomView(Context context) {
setDrawingCacheEnabled(true);
drawnFlag = false;
}
в своем onDraw
способ, вам понадобится что-то вроде этого:
public void onDraw(Canvas canvas) {
if (! drawnFlag) {
canvas.drawPath(...);
canvas.drawPath(...);
drawnFlag = true;
}
}
теперь прокрутка на этом пользовательском представлении должна быть гладкой, так как мы только вызовите методы рисования один раз.
Afaik ScrollView устанавливает правильный клип rect на холсте, который ваш вид получает в onDraw, поэтому вам нужно только нарисовать то, что внутри этого rect. Вы также можете реализовать растровые изображения кэша на основе размера клипа rect.