Tôi đang cố gắng xây dựng một ứng dụng thực tế tăng cường cho Android và đã gặp phải vấn đề về phân lớp bề mặt. Tôi cần một cái nhìn bề mặt để hiển thị xem trước máy ảnh mà tôi sẽ lớp phủ đồ họa, và tôi cần một bề mặt để vẽ đồ họa của tôi trên. Bề mặt thứ hai này cũng cần được vẽ phía trên bản xem trước của máy ảnh nhưng có nền trong suốt. Trong triển khai hiện tại của tôi, tôi có cả hai chế độ xem bề mặt hoạt động và xuất hiện như chúng được cho là, nhưng nền không trong suốt và do đó không có giao diện thứ hai với đồ họa được chồng lên trên mặt xem trước của máy ảnh. Làm thế nào điều này có thể đạt được? Khi tìm kiếm nhiều câu hỏi tràn ngăn xếp cũng như các diễn đàn khác, tôi đã gặp nhiều ý kiến mâu thuẫn liên quan đến vấn đề này. Một số người cho rằng việc xem lớp bề mặt trong Android là không thể khi người khác nói rằng đó là vấn đề sử dụng bố cục khác (FrameLayout so với LinearLayout?) Cụ thể, triển khai của tôi bao gồm hai chế độ xem: một lớp, CustomCameraView, mở rộng SurfaceView và một lớp , CustomDrawView, cũng mở rộng SurfaceView chứa trong FrameLayout với CustomDrawView xuất hiện sau CustomCameraView. Làm thế nào chúng có thể được xếp lớp để CustomDrawView có vẻ chồng lên trên CustomCameraView?Layered SurfaceViews trong FrameLayout trong Android
Trả lời
Tôi nghĩ rất nhiều người đã thử điều này. Google Enginee đã nêu rõ (here) rõ ràng rằng bạn nên tránh xếp chồng Chế độ xem bề mặt. Ngay cả khi ai đó đã tìm thấy một số mẹo để làm điều đó, nó có lẽ không tương thích và sẽ dẫn đến các vấn đề.
Tôi nghĩ rằng điều này mang lại ba lựa chọn, tùy thuộc vào yêu cầu của bạn:
- View (s) trên đầu Surface Xem
Sử dụng Surface Xem cho xem trước Camera và chồng Quan điểm về đầu của nó. Điểm bất lợi của phương pháp này là vẽ trên các khung nhìn "bình thường" a) chậm hơn và b) diễn ra trong chuỗi giao diện người dùng. Bạn có thể nhận được xung quanh b) nếu bạn thực hiện các chủ đề chính mình. Nhưng nói chung, đó có lẽ là cách để đi nếu lớp phủ của bạn chứa một cái gì đó giống như các yếu tố giao diện người dùng hoặc một vài Drawables mà không cần phải được cập nhật quá thường xuyên.
- làm tất cả mọi thứ trong một SurfaceView
này sẽ cung cấp hiệu suất tốt hơn yo và ít chi phí trong thời gian chạy. Bạn chỉ có một SurfaceView. Composite các lớp phủ trên SurfaceView của bạn và vẽ tất cả mọi thứ ở đó. Tất nhiên, bạn có thể kết hợp cả hai cách tiếp cận.
- làm tất cả mọi thứ trong một GLSurfaceView
Đây có lẽ là con đường để đi cho hiệu suất thực. Giống như trên, nhưng với chế độ xem máy ảnh, hiển thị kết cấu OpenGL theo số GLSurfaceView.
tôi đã làm việc này có 2 quan điểm minh bạch trên SurfaceView của máy ảnh bằng cách sử dụng phương pháp sau đây:
hoạt động của tôi thiết lập tất cả các quan điểm của mình trong phương pháp onCreate()
, tôi làm không sử dụng bất kỳ file layout cho điều đó. Nó trông giống như sau:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(null); //savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
cameraPreview = new CameraPreview(this);
addContentView(cameraPreview, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
animationView = new AnimationView(this);
addContentView(animationView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
crosslinesView = new CrosslinesView(this);
addContentView(crosslinesView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
}
cameraPreview
là loại SurfaceView
, animationView
và crosslinesViews
là loại View
. onDraw()
của 2 chế độ xem thứ hai trông giống như sau:
protected void onDraw(Canvas canvas) {
// Have the view being transparent
canvas.drawARGB(0, 0, 0, 0);
// Your drawing code goes here
// ...
}
Chúc may mắn!
Bạn có nhớ đăng mã XML của chế độ xem và có thể là màn hình nhanh không? Sau đó, một số người có thể kiểm tra và hiểu. –