Оптимизация Функцией 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.