Могу ли я аннулировать весь экран при каждом звонке?

Я новичок в разработке Android и читаю книгу Hello Android . Он использует пример Sudoku, и код, который я имею в виду, здесь.

В этом случае onTouchScreen он вызывает метод select, который вызывает недействительность дважды. Вопрос в том, что при invalidating метод onDraw называется сразу после этого? Так будет в этом случае, внутри моего метода выбора, он будет делать

  1. аннулировать
  2. Вызвать onDraw
  3. Сделайте что-нибудь
  4. аннулировать
  5. Вызвать onDraw

Так ли это будет, также, будет ли регенерирован весь экран? Все номера и подсказки и т. Д., Потому что из книги автор говорит

В более ранней версии этого примера я отключил весь экран всякий раз, когда курсор был перемещен. Таким образом, при каждом нажатии клавиши вся головоломка должна была быть перерисована. Это заставило его заметно отстать. Переключение кода, чтобы аннулировать только самые маленькие прямоугольники, которые изменили, заставило его работать намного быстрее.

Что именно он пытается здесь сказать?

Добавлена ​​информация

Я добавил несколько журналов в методе onDraw, некоторые в начале, некоторые в цикле for. Всякий раз, когда я касался нового прямоугольника, все журналы были вызваны. Разве это не означает, что весь экран переполняется, поскольку весь код в onDraw повторно выполняется?

Kraken

Q: Но как насчет журналов, конечно, если мои циклы выполняются, это означает, что все canvas.draw тоже будет выполнено?
A: Да, весь рисунок будет выполнен в вашем примере кода. Вы должны оптимизировать процесс рендеринга самостоятельно, в методе onDraw .

В: Как система знает, какой фрагмент кода «только» перекроет грязную область?
A: Canvas::getClipBounds даст вам грязный прямоугольник, на который вы должны нарисовать что-то.
Внутри for loop в onDraw сравните грязный прямоугольник с прямоугольником, который вы хотите нарисовать. Затем continue если они не пересекаются.

Но помните, что если у вас есть несколько областей, загрязненных, возвращенный прямоугольник будет объединением всех грязных областей.
Ниже приведены следующие два вопроса:
Получение грязной области внутри рисования ()
Android: invalidate (грязный)

Надеюсь, что это поможет вам.

==========================

Автор прав. Но это все еще можно оптимизировать.

Вызов invalidate(Rect) автоматически установит область клипа для холста. (Вот почему canvas.getClipBounds() может вернуть эту область).
Затем, во время onDraw() , onDraw() извлечение из области клипа будет проигнорировано. Они не отображаются на экране, поэтому ДЕЙСТВИТЕЛЬНО уменьшают время рисования.
Но игнорировать их по-прежнему стоит накладные расходы. Поэтому для графического интенсивного приложения onDraw() может быть лучше оптимизирован, если вы исключите их заранее.

Вы можете найти отличный пример для оптимизации onDraw() в Android- KeyboardView Android, который обеспечивает представление вашего метода ввода вашего Android. http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/inputmethodservice/KeyboardView.java

Это непосредственно из документации View :

Рисование обрабатывается путем ходьбы по дереву и визуализации каждого вида, которое пересекает недопустимую область. Поскольку дерево перемещается по порядку, это означает, что родители будут рисовать до (т. Е. Позади) своих детей, с братьями и сестрами, выполненными в том порядке, в котором они появляются в дереве. Если вы установите фоновый чертеж для представления, тогда представление будет рисовать его для вас, прежде чем переходить к его методу onDraw ().

Обратите внимание, что структура не будет отображать представления, которые не находятся в недопустимой области. `

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

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

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

Что еще более важно, видите ли вы какое-либо улучшение после использования области invalidate vs full invalidate?

Даже если вы вызываете invalidate несколько раз, метод onDraw будет вызываться только один раз. В основном, onDraw получает вызов внутри метода RunLoop, когда представление было признано недействительным. Это означает, что если вы несколько раз аннулируете представление, прежде чем возвращать элемент управления runloop, представление будет перерисовываться только один раз. Обратите внимание, что если вы аннулируете два разных прямоугольника представления, система попытается сделать объединение этих прямоугольников перед перерисовкой вашего представления.

В коде недействительным, о котором вы говорите, является следующее:

  invalidate(selRect); 

?

Если он только вызывает onDraw этого выбранного прямоугольника selRect .

Только invalidate(); Перерисовывает экран отверстия.

Надеюсь, поможет.

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

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

Из документации для Android:

Если вид виден, в будущем он будет вызываться onDraw (android.graphics.Canvas).

Зная, что внутри метода select это, вероятно, произойдет: 1. Недействительность небольшой части представления 2. Сделайте некоторые вещи 3. Неверьте другую небольшую часть представления 4. Тезисы 2 части представления перерисовываются

Надеюсь, что это помогло.