2013-03-21 2 views
17

TL; DR: Поскольку getDrawingCache(), похоже, вызывает полную переделку View, когда аппаратное ускорение включено, есть ли альтернативное средство получения Bitmap (или что-то в этом роде), которое позволяет избежать этого, возможно, путем чтения данных, заполненных в (аппаратного, программного), когда последний раз нарисовал View?Эффективные "Скриншоты" просмотра?


Некоторые фона:

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

Android 4.2 добавлен Presentation, чтобы приложения могли размещать произвольные материалы на «втором экране» (например, на экране HDMI). В этом случае время от времени было бы полезно, чтобы второй экран показывал часть того, что находится на дисплее основного планшета. Если вы считаете, что презентационное программное обеспечение, такое как Microsoft PowerPoint, LibreOffice Impress и т. П., В типичных настройках с двумя экранами, аудитория видит текущий слайд презентации, а ведущий видит текущий слайд и записи таймера и динамиков и ...

Для неинтерактивного контента, такого как PNG, представляющий слайд, это просто вопрос отображения одного и того же изображения на обоих экранах (наряду с другими материалами на основном экране).

Однако для интерактивного контента, такого как WebView, иногда бывает трудно сделать такое зеркалирование. Например, у нас нет хорошего способа узнать, когда содержимое WebView может измениться, так как это может быть сделано на основе данных, только в пределах самого WebView (например, завершения вызовов AJAX), а не в том, что мы делаем отдельно. И даже если мы сделали, узнаем, когда изменилось содержание WebView, у нас нет хорошего способа получить какой-либо другой WebView, чтобы отобразить тот же контент.

Так я решил попробовать создать MirroringFrameLayout, который будет использовать getDrawingCache() для извлечения Bitmap содержимого контейнера и доставить, что кому-то, кто может оказать его на экране (например, ImageView, показанной в Presentation).

Однако, с аппаратным ускорением включено, setDrawingCacheEnabled(true)is somewhat of a no-op:

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

getDrawingCache() Вызов в этих случаях заставляет полный draw() в View к растровым спинками Canvas, а не на самом деле, используя кэш. Так как draw() может быть дорогостоящим, часто делает draw() (скажем, срабатывает через postOnAnimation()) приводит к удару.

Следовательно, я пытаюсь определить, есть ли еще какой-то «кэш чертежа», за пределами getDrawingCache(), который мы можем использовать с включенным аппаратным ускорением, которое может быть использовано для настройки этого зеркалирования, и это более эффективно.Из того, что я вижу, такого кеша нет, поскольку слои эффективно записываются только с точки зрения приложений SDK. Однако я надеюсь, что, возможно, мне не хватает какого-либо решения.

Заранее благодарен!

+0

FYI, здесь репозиторий GitHub, содержащий мою реализацию: https://github.com/commonsguy/cwac-layouts – CommonsWare

ответ

13

Вы можете использовать setLayerType(View.LAYER_TYPE_SOFTWARE, null), но он будет иметь побочный эффект от того, что просмотр медленнее, чтобы перерисовывать каждый раз, когда он обновляется. Было бы гораздо эффективнее создать пользовательский ViewGroup, который рисует ваш вид на двух холстах (по одному для каждого экрана). Вы также можете просто использовать ViewTreeObserver и на каждом обратном вызове обратить внимание на визуализацию на втором экране. Я действительно рекомендую вам не пытаться злоупотреблять типом/типом чертежа для такого варианта использования.

+0

Безопасно ли мне отображать отдельную 'Canvas' из' onDraw() 'в пользовательском 'ViewGroup'? – CommonsWare

+0

До тех пор, пока это из потока пользовательского интерфейса, да. –

+0

Хорошо, пока это работает. Следующий проект: получение правильного масштабирования, так как размер зеркала не может быть идентичен размеру оригинала. Чтобы процитировать страницу «Масштабирование взгляда», «Yay, math». :-) Благодаря! – CommonsWare

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