Когда необходимо выполнить invalidate() в представлении?
Мой ответ на этот вопрос был только что принят, но я начал задаваться вопросом, когда именно нужно аннулировать () представление, а когда это не нужно?
Подумав немного, я пришел к выводу, что он должен работать примерно так:
- фактическое рисование "всего" происходит после
onResume()
- в "свободное" время части экрана могут быть перерисованы, но только те, которые были
invalidated
(и все под ним)
Поэтому, казалось бы, если я что-то поменяю после onResume()
(например, в ответ на нажатие кнопки, я должен invalidate()
измененный View
).
Однако, из того, что говорит scana в этом вопросе, оно должно быть более сложным, чем это, и это зависит от того, какой метод используется.
Например, используется ли
lastClicked.setImageBitmap();
или же
lastClicked.setImageResource();
Итак, когда необходимо выполнить invalidate() в View и как это действительно работает?
3 ответа
Обычно система обрабатывает изменение размера, скрытие, отображение и множество других вещей для ваших виджетов автоматически, но иногда возникают проблемы, если базовый буфер для прорисованных пикселей или вспомогательных данных изменился или устарел (вы меняете ресурс изображения на View или изменения в наборе необработанных данных). Это происходит потому, что ОС не может знать, что данные изменились особым образом.
В этих случаях, когда вы имеете дело с рисованием, вы должны сообщить системе, что лежащие в ее основе данные не находятся в хорошем состоянии, с помощью Widget.invalidate() и повторное рисование ставится в очередь в главном потоке, как вы упомянули. В зависимости от реализации системы и версии Android то, что отслеживается для изменений системой, варьируется, но обычно я предполагаю, что системные ресурсы (байтовые массивы, массивы символов, индексы ресурсов, рисование контекста вручную) не отслеживаются и требуют аннулирования и все остальное будет обрабатываться системой.
(Не забудьте принять некоторые ответы)
В общем-то, invalidate()
означает "перерисовать на экране" и приводит к вызову представления onDraw()
метод. Так что, если что-то меняется, и это нужно отразить на экране, вам нужно позвонить invalidate()
, Тем не менее, для встроенных виджетов вам редко, если вообще нужно, называть его самостоятельно. При изменении состояния виджета внутренний код будет вызывать invalidate()
по мере необходимости, и ваши изменения будут отражены на экране. Например, если вы звоните TextView.setText()
после выполнения внутренней обработки (будет ли текст помещаться на экране, нужно ли выполнять многоточие и т. д.), TextView
позвоню invalidate()
до setText()
возвращается. Аналогично для других виджетов.
Если вы реализуете пользовательский вид, вам нужно будет позвонить invalidate()
всякий раз, когда изменяется модель поддержки, и вам нужно перерисовать ваш взгляд. Он также может быть использован для создания простых анимаций, где вы меняете состояние, затем вызываете invalidate()
изменить состояние снова и т. д.
Помните, что рисование на экране - это частый процесс, и всякий раз, когда вы обновляете представление, это изменение должно распространяться и перерисовываться, чтобы правильно уведомить о таком изменении. invalidate()
это метод триггера, который вынуждает перерисовывать любое представление, для которого вы хотите показать изменения.
У меня была эта проблема, когда я хотел нарисовать textPaint! Мой код был
canvas.drawPaint(textPaintNumber)
canvas.drawText("MyText", 30F, 63F, textPaintNumber)
Я очистил первый ворс и проблема была решена
canvas.drawText("MyText", 30F, 63F, textPaintNumber)