How to draw an overlay on a SurfaceView used by Camera on Android?
android, camera, surfaceview
Solution
`SurfaceView` probably does not work like a regular `View` in this regard.
Instead, do the following:
- Put your `SurfaceView` inside of a `FrameLayout` or `RelativeLayout` in your layout XML file, since both of those allow stacking of widgets on the Z-axis
- Move your drawing logic into a separate custom `View` class
- Add an instance of the custom View class to the layout XML file as a child of the `FrameLayout` or `RelativeLayout`, but have it appear after the `SurfaceView`
This will cause your custom `View` class to appear to float above the `SurfaceView`.
Problem
I have a simple program that draws the preview of the `Camera` into a `SurfaceView`. What I'm trying to do is using the `onPreviewFrame` method, which is invoked each time a new frame is drawn into the `SurfaceView`, in order to execute the `invalidate` method which is supposed to invoke the `onDraw` method. In fact, the `onDraw` method is being invoked, but nothing there is being printed (I guess the camera preview is overwriting the text I'm trying to draw). This is a simplify version of the `SurfaceView` subclass I have: ``` public class Superficie extends SurfaceView implements SurfaceHolder.Callback { SurfaceHolder mHolder; public Camera camera; Superficie(Context context) { super(context); mHolder = getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(final SurfaceHolder holder) { camera = Camera.open(); try { camera.setPreviewDisplay(holder); camera.setPreviewCallback(new PreviewCallback() { public void onPreviewFrame(byte[] data, Camera arg1) { invalidar(); } }); } catch (IOException e) {} } public void invalidar(){ invalidate(); } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(w, h); camera.setParameters(parameters); camera.startPreview(); } @Override public void draw(Canvas canvas) { super.draw(canvas); // nothing gets drawn :( Paint p = new Paint(Color.RED); canvas.drawText("PREVIEW", canvas.getWidth() / 2, canvas.getHeight() / 2, p); } } ```