Как правильно использовать setZOrderMediaOverlay на Android?

Как и многие другие, я пытаюсь рисовать 3D-объекты (используя GLSurfaceView) при предварительном просмотре камеры (используя SurfaceView), а также некоторые кнопки, расположенные сверху. На самом деле у меня прототип работает, но я не смог заставить onResume работать правильно. После возобновления GLSurfaceView остается позади и больше не виден. Я знаю, что он работает, потому что я вижу чертеж отлично, если я удаляю SurfaceView из макета.

Целью является Nexus One, работающий запас 2.3.3 ROM.

Вот макет xml:

 <com.example.cameratest.GLPreview android:id="@+id/cubes" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <com.example.cameratest.Preview android:id="@+id/camera" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/buttongroup" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_gravity="right" android:gravity="center"> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonClose"></Button> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonMode"></Button> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/buttonCameraInfo"></Button> </LinearLayout> 

Все это завернуто в блок <merge> , но по какой-то причине я не смог включить его в приведенный выше <code> листинг. Preview – это класс, который расширяет SurfaceView и реализует логику предварительного просмотра камеры.

Это срабатывает при запуске этой операции. После запуска другого действия (например, нажатием одной из кнопок) и завершения этой операции основное действие возобновляется, но 3D-объекты больше не видны.

Я нашел это обсуждение, где упоминается, что setZOrderMediaOverlay() поможет исправить эту проблему z-порядка. Кроме того, в документе Android для setZOrderMediaOverlay () говорится, что эта функция должна быть вызвана «до того, как окно, содержащее вид поверхности, будет прикреплено к оконному менеджеру». Я не знаю, как я должен интерпретировать этот оператор, поэтому я помещал в код операторы отладки, чтобы увидеть последовательность событий. Вот как GLSurfaceView код GLSurfaceView :

 public class GLPreview extends GLSurfaceView { private static final String TAG = "GLPreview"; public GLPreview(Context context, AttributeSet attrs) { super(context, attrs); // this.setZOrderMediaOverlay(true); } public void onPause() { super.onPause(); Log.d(TAG, "GLPreview: OnPause"); } public void onResume() { // this.setZOrderMediaOverlay(true); super.onResume(); Log.d(TAG, "GLPreview: OnResume"); } public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "GLPreview: surfaceCreated"); super.surfaceCreated(holder); } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { Log.d(TAG, String.format("GLPreview: surfaceChanged, format=%d, w=%d, h=%d", format, w, h)); super.surfaceChanged(holder, format, w, h); } public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG, "GLPreview: surfaceDestroyed"); super.surfaceDestroyed(holder); } protected void onAttachedToWindow() { Log.d(TAG, "GLPreview: onAttachedToWindow"); super.onAttachedToWindow(); } protected void onDetachedFromWindow() { Log.d(TAG, "GLPreview: onDetachedFromWindow"); super.onDetachedFromWindow(); } protected void onWindowVisibilityChanged (int vis) { String newVisibility; switch (vis) { case View.GONE: newVisibility = "GONE"; break; case View.INVISIBLE: newVisibility = "INVISIBLE"; break; case View.VISIBLE: newVisibility = "VISIBLE"; break; default: newVisibility = String.format("Unknown constant %d", vis); } Log.d(TAG, String.format("GLPreview: onWindowVisibilityChanged -> %s", newVisibility)); super.onWindowVisibilityChanged(vis); } }
public class GLPreview extends GLSurfaceView { private static final String TAG = "GLPreview"; public GLPreview(Context context, AttributeSet attrs) { super(context, attrs); // this.setZOrderMediaOverlay(true); } public void onPause() { super.onPause(); Log.d(TAG, "GLPreview: OnPause"); } public void onResume() { // this.setZOrderMediaOverlay(true); super.onResume(); Log.d(TAG, "GLPreview: OnResume"); } public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "GLPreview: surfaceCreated"); super.surfaceCreated(holder); } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { Log.d(TAG, String.format("GLPreview: surfaceChanged, format=%d, w=%d, h=%d", format, w, h)); super.surfaceChanged(holder, format, w, h); } public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG, "GLPreview: surfaceDestroyed"); super.surfaceDestroyed(holder); } protected void onAttachedToWindow() { Log.d(TAG, "GLPreview: onAttachedToWindow"); super.onAttachedToWindow(); } protected void onDetachedFromWindow() { Log.d(TAG, "GLPreview: onDetachedFromWindow"); super.onDetachedFromWindow(); } protected void onWindowVisibilityChanged (int vis) { String newVisibility; switch (vis) { case View.GONE: newVisibility = "GONE"; break; case View.INVISIBLE: newVisibility = "INVISIBLE"; break; case View.VISIBLE: newVisibility = "VISIBLE"; break; default: newVisibility = String.format("Unknown constant %d", vis); } Log.d(TAG, String.format("GLPreview: onWindowVisibilityChanged -> %s", newVisibility)); super.onWindowVisibilityChanged(vis); } } 

Вот последовательность событий, когда я запускаю приложение:

 GLPreview: OnResume
 GLPreview: onAttachedToWindow
 GLPreview: onWindowVisibilityChanged -> VISIBLE
 GLPreview: surfaceCreated
 GLPreview: surfaceChanged, format = 1, w = 800, h = 480

Поэтому я предположил, что setZOrderMediaOverlay() нужно вызвать либо в onResume() либо в конструкторе. Тем не менее, я пробовал различные комбинации setZOrderMediaOverlay() с true или false , в GLSurfaceView или SurfaceView , но ни одна из них не помогла с этой проблемой.

Я относительно новичок в программировании на Android. Я зашел так далеко, но в этот момент мне нужна помощь. Если кто-то, кто использовал setZOrderMediaOverlay() успешно в этом сценарии и получил его работу с onResume() дайте мне знать, как это нужно сделать.

Заранее большое спасибо!

Я некоторое время боролся с одной и той же проблемой, но считаю, что теперь работает код ниже. (Он продолжает работать после паузы / блокировки независимо от того, включена или выключена камера).

Во-первых, у меня нет никаких просмотров и т. Д., Определенных в файле макета – они создаются в коде. Вызывается из основного метода onCreate () – Обратите внимание на setZOrderMediaOverlay () на augScreen.

Я не делал ничего особенного внутри onPause () или onResume (), кроме передачи onPause () и onResume () до augScreen.

  // 1 - Camera Preview camScreen = new CameraPreview(this); setContentView(camScreen, new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); // 2 - 3D object display augScreen = new AR_SurfaceView(this, getViewRange()); addContentView(augScreen, new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); augScreen.setZOrderMediaOverlay(true); // 3 - Permanent overlay RelativeLayout overlayScreen = new OverlayView(this); addContentView(overlayScreen, new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); overlayScreen.setVisibility(View.VISIBLE); // 4 - UI buttons (toggleable) uiScreen = new UserInterfaceView(this); addContentView(uiScreen, new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 

Ответ Awila_Tech мне тоже помог. Я использовал GLSurfaceView и аккуратно называл его onPause и onResume в onPause и onResume деятельности, но 1 из 5 раз мой экран оставался черным, когда вызывался фактический onDrawFrame.

Обобщить:

 public class OpenGLApp extends Activity implements GLSurfaceView.Renderer { private GLSurfaceView mGLSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLSurfaceView = new GLSurfaceView(this); mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8); mGLSurfaceView.setRenderer(this); mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); mGLSurfaceView.setKeepScreenOn(true); mGLSurfaceView.setDrawingCacheEnabled(true); mGLSurfaceView.setZOrderOnTop(true); setContentView(mGLSurfaceView); //... } @Override protected void onPause() { //... mGLSurfaceView.onPause(); super.onPause(); } @Override protected void onResume() { mGLSurfaceView.onResume(); //... super.onResume(); } } 
Intereting Posts
Эмулированное Android-устройство не синхронизирует время и дату после восстановления моментального снимка Как удалить все пространство вокруг диаграммы в AndroidPlot? Вкладки ActionBar с фрагментами для поворота Токен доступа удален при получении информации пользователя из facebook Является ли андроид: showAsAction не рекомендуется? Android: Как отслеживать, открывается ли открытая клавиатура? Android Studio Picasso gif загрузка изображения для заполнителя Как сделать кнопочный щелчок и просмотреть элемент списка нажмите в настройке просмотра списка в android В конструкции Android gradle измените содержимое strings.xml во время сборки Как предоставить доступ к странице игровых сервисов Google Play Developer Console другим учетным записям? Firebase: могу ли я использовать новую учетную запись Facebook для аутентификации пользователей приложений? ANDROID – ExpandableListView SwipeRefreshLayout из библиотеки поддержки. V21 не работает со статическим содержимым SurfaceView отображает черный экран – Android Тост, идущий несколько раз