2012-04-13 3 views
6

У меня есть библиотека для рисования, и с ней у меня есть пользовательский вид. Когда необходимо выполнить какие-либо обновления, библиотека вызывает метод отображения invalidate(). И тогда вызывается метод onDraw(), и все работает нормально.View.invalidate(), кажется, не вызывает View.onDraw()

Однако, когда я добавляю атрибут usesSdkVersion="14" к моему AndroidManifest.xml file, это перестает работать. Больше не используется метод моего вида onDraw().

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Кажется, что когда я вызываю invalidate() в результате нажатия кнопки в моем приложении, просмотр обновляется, как ожидалось. Кроме того, в моей библиотеке есть одна анимация, которая работает правильно. Поэтому, по-видимому, он работает правильно. Но большую часть времени он не перерисовывается. Есть ли какое-либо состояние, в котором может быть пользовательский вид, который заставит ОС пропустить перерисовку после вызова invalidate()?

+0

Вы все еще называете это из потока пользовательского интерфейса? иначе вы должны использовать postInvalidate(). – Heinrisch

+0

Я попытался изменить invalidate на postInvalidate, чтобы проверить это, и проблема все еще существует. – Rickster

+0

Включено или выключено аппаратное ускорение? –

ответ

5

Из андроида 3.0 при использовании аппаратного ускорения рисунок просмотров записывается и сохраняется на графическом процессоре.

Итак, когда вы получили два вида: А выше В, и вы называете B.invalidate, B.onDraw будет называться и запись на GPU, но A.onDraw не будет называться, потому что это уже записано!

Это отличается от режима не-аппаратного ускорения, когда вызывались все виды onDraw.

2

официальных документы:

Однако, поскольку аппаратное ускорение не поддерживается для всех 2D операций рисования, превращая его может повлиять на некоторых из ваших приложений, которые используют собственные представления или рисованные вызовы. Проблемы обычно проявляются как невидимые элементы, исключения или ошибочно отображаемые пиксели.

Чтобы исправить это, Android дает возможность включить или отключить аппаратное ускорение на следующих уровнях:

Применение

<application android:hardwareAccelerated="true" ...> 

активность

.

Окно

GetWindow() setFlags (WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

Посмотреть

myView.setLayerType (View.LAYER_TYPE_SOFTWARE, нуль);

Я проверяю на мой взгляд.

1

Это похоже на ошибку в Android. Вместо Invalidate() попытаться использовать метод с тем же именем с четырьмя параметрами:

view.invalidate(0,0,view.getWidth(), view.getHeight()); 

Кстати, это лучшая практика для аннулирует только ту область, которая меняется. Пройдите левой, верхней, правой, нижней координатами недействительной области.