2014-01-09 6 views
5

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

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

  1. Invalidate
  2. вызов OnDraw
  3. Есть некоторые вещи
  4. Invalidate
  5. вызова OnDraw

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

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

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

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

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

ответ

5

Kraken

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

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

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

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

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

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

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

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

+0

@ ZhenghonghWang Я не уверен, правильно ли я понял, я установил что-то грязное, и в моем коде, в методе onDraw, я действительно не получаю грязную часть явно. так вы говорите, что в моем случае все будет сделано? Потому что, по словам автора, он сделал это оптимальным образом и будет оказывать только грязную часть. – Kraken

+0

Да, автор, о котором вы говорили, прав. Но процесс рисования может быть оптимизирован лучше. Я обновил свой ответ. –

+1

Invalidate with rect не изменяет границы холста с аппаратным ускорением. Весь вид всегда перерисовывается независимо от того, был ли прямоугольник передан Invalidate. – jjxtra

0

В коде Invalidate, что вы говорите это:

invalidate(selRect); 

?

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

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

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

+0

Пожалуйста, следуйте комментариям по другому ответу и предоставьте ответ на мои вопросы, пожалуйста. Благодарю. – Kraken

0

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

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

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

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

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

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

+0

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

+0

Когда я говорю «весь экран», я имею в виду весь вид. – Kraken

+0

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

2

Это непосредственно из View documentation:

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

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

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

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

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

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

1

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

Смежные вопросы