2014-12-22 4 views
0

Я создаю макет типа FrameLayout, в котором я добавляю два вида. Два представления - объекты GLSurfaceView и SurfaceView соответственно. Согласно документации разработчиков Android относительно SurfaceView,SurfaceView скрывает другие компоненты на экране

«Поверхность Z заказана так, что она находится за окном, удерживающим SurfaceView, SurfaceView пробивает отверстие в своем окне, чтобы его поверхность отображалась».

Это хорошо работает для меня, и SurfaceView всегда остается за моим GLSurfaceView (используется для рисунков opneGL). Но после того, как возобновление внешнего события поведение нечетно для следующей конфигурации

Android Версия: 4,3 устройства Номер модели: Nexus 7 Версия ядра 3.4.0.g1f57c39 13 июня постройки Номер: JWR66N

Для эта конфигурация, возобновляющаяся после внешнего события, помещает мой GLSurfaceView за SurfaceView. Другими словами, SurfaceView размещается сверху в ZOrder, и мои рисунки OpenGL больше не видны. В версиях, превышающих Android 4.3, такого поведения не наблюдается.

Я могу воспроизвести это поведение во всех версиях, вызвав метод SurfaceView следующим образом: true в качестве параметра.

аннулируются setZOrderOnTop

Это известная проблема. Кто-нибудь может помочь мне в этом?

С уважением, Sumedh

+0

Держу пари, что его устройство зависит ... отверстие вещь не очень надежна и подвержена артефактам на свитках, ретрансляциях, резюме ... – rupps

+0

Какая альтернатива. Я хочу поместить некоторые элементы управления видео, какие макеты, виды можно использовать. Можете ли вы указать мне на что-то ....... –

+0

umm вы двигаетесь близко к краю! взгляните на http://stackoverflow.com/questions/5647824/android-multiple-surfaceviews, они, похоже, обсуждают укладку поверхностных изображений – rupps

ответ

3

SurfaceViews имеют две части, поверхность и вид. Поверхность - полностью независимый слой. Вид есть, поэтому код макета UI должен работать. Как правило, вид просто прозрачный черный, поэтому вы можете видеть все, что находится за ним.

GLSurfaceView - это просто SurfaceView с некоторым кодом для управления контекстами EGL и потоками. Под ним просто SurfaceView. Поэтому, если у вас есть как SurfaceView, так и GLSurfaceView, и они имеют одинаковые размеры и Z-порядок, тогда один из них собирается «выиграть», а другой собирается «проиграть», потому что они пытаются заняться тем же пространство в то же время. Не существует определенного значения, для которого он будет «выигрывать», поэтому ожидается несовместимое поведение.

Один из способов избежать столкновений - оставить один набор по умолчанию Z и вызвать setZOrderMediaOverlay() с другой. «Оверлей мультимедиа» по-прежнему находится за интерфейсом пользователя, но выше позиции по умолчанию. Если вы используете setZOrderOnTop(), поверхность также будет расположена над пользовательским интерфейсом.

Верхняя поверхность должна быть визуализирована с прозрачными пикселями, если вы хотите увидеть что-то за ней (так же, как вид должен быть прозрачным, чтобы увидеть поверхность).

Самый эффективный способ избежать этой проблемы - не иметь этой проблемы: используйте один SurfaceView для всего, предоставив для него весь свой контент, не относящийся к пользовательскому интерфейсу. Для этого требуется немного больше работы (и, возможно, SurfaceTexture), если вы показываете видео или показываете предварительный просмотр камеры на одной из поверхностей.

Вы можете найти несколько примеров в Grafika. «multi-surface exerciser» демонстрирует три перекрывающиеся SurfaceViews, отображаемые в программном обеспечении, перекрывающиеся с элементами пользовательского интерфейса. Другие действия показывают способы работы с Surfaces, GLES, камерой и видео.

См. Также документ Android System-Level Graphics Architecture, в котором объясняется все это более подробно.

+0

Спасибо. Я сделал точно так же, как вы объяснили. Вот что я делаю, у меня есть два вида: 1. GLSurfaceView (рисует графику, созданный каркасом Cocos2dx), 2. SurfaceView (Renders Video, Media Player). Я хочу, чтобы моя графика cocos2dx всегда была поверх видео, поэтому я вызываю setZOrderMediaOverlay() для GLSurfaceView. Предполагаю, что, поскольку я не устанавливаю параметр ZOrder для SurfaceView, он по умолчанию и будет всегда Z упорядочен ниже GLSurfaceView. Наложение правильно работает с устройствами, использующими ОС, которая выше, чем Jelly bean, для Jelly Bean это не работает. Я что-то пропустил ... или иначе .. –

+0

Я также просмотрел документ графической архитектуры уровня системы. Единственный способ, с помощью которого я могу связать его с Jelly bean, - «Структура данных в настоящее время всегда создается и« принадлежит »потребителю. В Android 4.3 только сторона производителя была« привязана », то есть производитель мог находиться в удаленном процессе, но потребитель должен был жить в процессе создания очереди. Это немного изменилось в 4.4, продвигаясь к более общей реализации. », но я не думаю, что у этого было бы что-то с Z-заказом. Правильно ли я –

+1

Если вы хотите два наложения вам нужно будет убедиться, что один сверху (GLSurfaceView) использует правильный цветной формат и пиксели рендеринга с непрозрачной альфа. Вы можете подтвердить порядок и цветной формат с помощью 'adb shell dumpsys SurfaceFlinger', глядя на секцию сводки аппаратного композитора (вырезанная версия появляется в двух местах на графической архитектуре doc - поверхности перечислены в обратном порядке заказ). Вызов Z-порядка должен происходить * до *, поверхность создается; Я не помню, сможет ли GLSurfaceView сделать это. Можете ли вы использовать простой SurfaceView с Cocos2dx? – fadden

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