Comment dessiner une superposition sur un SurfaceView utilisé par Camera sur Android?

J’ai un programme simple qui dessine l’aperçu de la Camera dans un SurfaceView . Ce que j’essaie de faire, c’est d’utiliser la méthode onPreviewFrame , qui est appelée chaque fois qu’une nouvelle image est dessinée dans SurfaceView , afin d’exécuter la méthode invalidate qui est supposée appeler la méthode onDraw . En fait, la méthode onDraw est appelée, mais rien n’est imprimé (je suppose que l’aperçu de la caméra écrase le texte que j’essaie de dessiner).

Ceci est une version simplifiée de la sous-classe SurfaceView j’ai:

 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); } } 

SurfaceView ne fonctionne probablement pas comme une View normale à cet égard.

Au lieu de cela, procédez comme suit:

  1. Placez votre SurfaceView intérieur d’un FrameLayout ou d’un RelativeLayout dans votre fichier XML de mise en page, car ceux-ci permettent d’emstackr des widgets sur l’axe Z
  2. Déplacer votre logique de dessin dans une classe de View personnalisée distincte
  3. Ajoutez une instance de la classe View personnalisée au fichier XML de présentation en tant qu’enfant du FrameLayout ou du RelativeLayout , mais SurfaceView le apparaître après le SurfaceView

Cela entraînera votre classe de View personnalisée à apparaître au-dessus de SurfaceView .

Voir ici pour un exemple de projet qui SurfaceView panneaux contextuels au-dessus d’un SurfaceView utilisé pour la lecture vidéo.

Essayez d’appeler setWillNotDraw(false) partir de surfaceCreated :

 public void surfaceCreated(SurfaceHolder holder) { try { setWillNotDraw(false); mycam.setPreviewDisplay(holder); mycam.startPreview(); } catch (Exception e) { e.printStackTrace(); Log.d(TAG,"Surface not created"); } } @Override protected void onDraw(Canvas canvas) { canvas.drawRect(area, rectanglePaint); Log.w(this.getClass().getName(), "On Draw Called"); } 

et appeler invalidate partir de onTouchEvent :

 public boolean onTouch(View v, MotionEvent event) { invalidate(); return true; } 

Je pense que vous devriez d’abord appeler la méthode super.draw() avant de faire quoi que ce soit dans la méthode draw de surfaceView.