Giống như nhiều người khác, tôi đang cố gắng vẽ các đối tượng 3D (sử dụng GLSurfaceView) trên xem trước máy ảnh (sử dụng SurfaceView), cùng với một số nút được đặt ở trên cùng. Tôi thực sự có một nguyên mẫu làm việc, nhưng tôi không thể làm cho onResume hoạt động chính xác. Sau khi tiếp tục, GLSurfaceView vẫn ở lại và không hiển thị nữa. Tôi biết rằng nó đang làm việc, bởi vì tôi có thể thấy các bản vẽ tốt nếu tôi loại bỏ các SurfaceView từ bố trí.Cách sử dụng đúng setZOrderMediaOverlay trên Android?
Mục tiêu là Nexus One, chạy ROM 2.3.3.
Đây là xml bố trí:
<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>
Tất cả điều này được bọc trong một khối <merge>
, nhưng đối với một số lý do, tôi không thể bao gồm nó trong <code>
niêm yết trên. Preview
là lớp mở rộng SurfaceView
và triển khai logic xem trước máy ảnh.
Điều này hoạt động tốt khi hoạt động khởi chạy. Sau khi tôi khởi động một hoạt động khác (ví dụ, bằng cách nhấn một trong các nút) và kết thúc hoạt động đó, hoạt động chính sẽ tiếp tục nhưng các đối tượng 3D sẽ không hiển thị nữa.
Tôi tìm thấy this discussion nơi được đề cập rằng setZOrderMediaOverlay()
sẽ giúp khắc phục vấn đề đặt hàng z này. Ngoài ra, các Android document for setZOrderMediaOverlay() nói rằng chức năng này nên được gọi là "trước khi cửa sổ có chứa xem bề mặt được gắn vào trình quản lý cửa sổ". Tôi không biết làm thế nào tôi nên giải thích rằng tuyên bố, vì vậy tôi đặt các báo cáo gỡ lỗi trong mã để xem chuỗi các sự kiện. Dưới đây là cách mã GLSurfaceView
trông giống như:
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);
}
}
Đây là chuỗi các sự kiện khi tôi khởi động ứng dụng:
GLPreview: OnResume GLPreview: onAttachedToWindow GLPreview: onWindowVisibilityChanged -> VISIBLE GLPreview: surfaceCreated GLPreview: surfaceChanged, format=1, w=800, h=480
Vì vậy, tôi cho rằng setZOrderMediaOverlay()
cần phải được gọi là trong cả hai onResume()
hoặc trong constructor. Tuy nhiên, tôi đã thử các kết hợp khác nhau của setZOrderMediaOverlay()
với true
hoặc false
, trong các lớp GLSurfaceView
hoặc SurfaceView
, nhưng không có kết quả nào giúp khắc phục sự cố.
Tôi khá mới khi nói đến lập trình Android. Tôi đã đi quá xa nhưng vào thời điểm này tôi cần sự giúp đỡ. Nếu ai đó đã sử dụng setZOrderMediaOverlay()
thành công trong trường hợp này và đã làm việc với onResume()
hãy cho tôi biết cách thực hiện điều này.
Cảm ơn rất nhiều trước!
FWIW, xem http://stackoverflow.com/questions/5648221/fighting-with-surfaceview-camera-and-opengl/25020225#25020225 đối với một số ghi chú về chồng chéo SurfaceViews. – fadden